9os

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 1c750154f5fa3f8521850512c911827e36bdb6df
parent e0b397f6b5f9021563e6309cbccda402d9afbd22
Author: Roberto Vargas <roberto.vargas@arm.com>
Date:   Mon,  5 Nov 2018 11:26:50 +0000

[debuglang] Integrate debuglang in the build system

Debuglang (previously hosted) was a totally independent
executable. This patch integrates it with the current
build system and with the code.

Change-Id: Ic74e25990ffb3bb81413d2229ee8ca3fab559546
Co-authored-by: Joel Hutton

Diffstat:
March/amd64/Makefile | 4++--
March/amd64/arch.c | 7++++++-
Darch/amd64/hosted.c | 324-------------------------------------------------------------------------------
March/amd64/ram.c | 1+
March/amd64/rom.c | 1+
March/arm64/Makefile | 2++
Mconfig/amd64-linux.mk | 1+
Minclude/rcode.h | 1+
Rscripts/genhosted.sh -> scripts/gendebuglang.sh | 0
Msrc/Makefile | 4++--
Asrc/debuglang/Makefile | 18++++++++++++++++++
Asrc/debuglang/debuglang.c | 336+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12 files changed, 370 insertions(+), 329 deletions(-)

diff --git a/arch/amd64/Makefile b/arch/amd64/Makefile @@ -1,8 +1,8 @@ PROJECTDIR = ../.. include $(PROJECTDIR)/scripts/rules.mk -ROMOBJS = crt-$(SYS).o arch.o rom.o $(SRCDIR)/romfw/builtin.o -RAMOBJS = crt-$(SYS).o arch.o rom.o $(SRCDIR)/ramfw/builtin.o +ROMOBJS = crt-$(SYS).o arch.o rom.o $(DEBUGLANG) $(SRCDIR)/romfw/builtin.o +RAMOBJS = crt-$(SYS).o arch.o rom.o $(DEBUGLANG) $(SRCDIR)/ramfw/builtin.o TARGET = $(BINDIR)/romfw.elf $(BINDIR)/ramfw.elf LIBS = -lhdl -lrmu -lc diff --git a/arch/amd64/arch.c b/arch/amd64/arch.c @@ -1,8 +1,13 @@ +#include <setjmp.h> #include <stdio.h> #include <stdlib.h> #include <rcode.h> + +jmp_buf recover; + + void halt(void) { @@ -12,7 +17,7 @@ halt(void) void swtch(struct trapframe *fp) { - panic("swtch() not implemented"); + longjmp(recover, 1); } void diff --git a/arch/amd64/hosted.c b/arch/amd64/hosted.c @@ -1,324 +0,0 @@ -#include <errno.h> -#include <rcode.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <hosted.h> - -void -print_tf(struct trapframe *tfp) -{ - printf("x0=0x%llx\tx1=0x%llx\tx2=0x%llx\tx3=0x%llx\n" - "x4=0x%llx\tx5=0x%llx\tx6=0x%llx\tx7=0x%llx\n" - "x8=0x%llx\tx9=0x%llx\tx10=0x%llx\tx11=0x%llx\n" - "x12=0x%llx\tx13=0x%llx\tx14=0x%llx\tx15=0x%llx\n" - "x16=0x%llx\tx17=0x%llx\tx18=0x%llx\tx19=0x%llx\n" - "x20=0x%llx\tx21=0x%llx\tx22=0x%llx\tx23=0x%llx\n" - "x24=0x%llx\tx25=0x%llx\tx26=0x%llx\tx27=0x%llx\n" - "x28=0x%llx\tx29=0x%llx\tx30=0x%llx\telr=%p\n" - "spsr=0x%llx\tesr=0x%llx\tfar=0x%llx\n" - "sp=0x%p\n", - tfp->x0, tfp->x1, tfp->x2, tfp->x3, - tfp->x4, tfp->x5, tfp->x6, tfp->x7, - tfp->x8, tfp->x9, tfp->x10, tfp->x11, - tfp->x12, tfp->x13, tfp->x14, tfp->x15, - tfp->x16, tfp->x17, tfp->x18, tfp->x19, - tfp->x20, tfp->x21, tfp->x22, tfp->x23, - tfp->x24, tfp->x25, tfp->x26, tfp->x27, - tfp->x28, tfp->x29, tfp->x30, tfp->elr, - tfp->spsr, tfp->esr, tfp->far, tfp->sp); -} - -/* Read a value in a given base between 2 and 16 0 means default base; - * 10, unless the string begins with "0x" or "0b" - */ -unsigned long long -base_read(char* str, int base, int *err) -{ - unsigned long long val; - char *endptr; - - endptr = NULL; - errno = 0; - val = strtoull(str, &endptr, base); - if (str == endptr || errno != 0){ - ERROR("strtoull error with '%s' in base %d\n", str, base); - if(err != NULL) - *err = 1; - } - return val; -} - -/* Get reg struct for named reg */ -unsigned long long* -get_named_reg(char* name, struct trapframe* tfp) -{ - size_t i; - char *regptr; - - regptr=NULL; - for(i=0;i<NUM_NAMED_REGS;i++){ - if(strcmp(name,named_regs[i].name)==0){ - regptr = (char*) tfp; - regptr += named_regs[i].offset; - } - } - return (unsigned long long*) regptr; -} - -/* Get rmc_command struct for named rmc command */ -const struct rmc_command* -get_rmc_cmd(char* name) -{ - size_t i; - - for(i=0;i<NUM_RMC_COMMANDS;i++){ - if(strcmp(name,rmc_commands[i].name)==0){ - return &rmc_commands[i]; - } - } - return NULL; -} - -/* Get command struct for named command */ -const struct command* -get_command(char* name) -{ - size_t i; - - for(i=0;i<NUM_COMMANDS;i++){ - if(strcmp(name,commands[i].name)==0){ - return &commands[i]; - } - } - return NULL; -} - -int -do_set(char** argv,int argc, struct trapframe* tfp) -{ - unsigned long long *reg=NULL; - unsigned long long setval=0; - unsigned int base; - int err; - - err = 0; - - reg = get_named_reg(argv[1],tfp); - if( reg == NULL){ - ERROR("Register '%s' not found\n",argv[1]); - return 1; - } - - base = 0; - - switch(argc){ - case 4: - base = base_read(argv[3], 10, &err); - if(err) - return 1; - /* fallthrough */ - case 3: - setval = base_read(argv[2], base, &err); - if(err) - return 1; - break; - default: - ERROR("Invalid number of parameters for set\n"); - return 1; - } - INFO("set:0x%llx\n",setval); - *reg=setval; - return 0; -} - -int -do_read(char** argv,int argc, struct trapframe* tfp) -{ - unsigned long long* reg=NULL; - char* format_string; - - reg = get_named_reg(argv[1],tfp); - if(reg == NULL){ - ERROR("Register '%s' not found\n",argv[1]); - return 1; - } - - switch(argc){ - case 3: - switch(atoi(argv[2])){ - case 10: - format_string="%llu\n"; - break; - case 16: - format_string="%llx\n"; - break; - default: - ERROR("Unsupported base for read:%s\nsupported: 10,16\n", - argv[2]); - return 1; - } - break; - case 2: - format_string="%llu\n"; - break; - default: - ERROR("Invalid number of arguments for read\n"); - return 1; - } - printf(format_string,*reg); - return 0; -} - -int -do_dump(char** argv,int argc, struct trapframe* tfp) -{ - print_tf(tfp); - return 0; -} - -int -do_trap(char** argv,int argc, struct trapframe* tfp) -{ - trap(tfp); - return 0; -} - -int -do_rmc(char** argv,int argc, struct trapframe* tfp) -{ - unsigned char class; - unsigned char func; - unsigned int base; - const struct rmc_command *rmc_cmd; - int err; - - err = 0; - - base = 0; - switch(argc){ - case 4: - base = base_read(argv[3], 10, &err); - if(err) - return 1; - /* fallthrough */ - case 3: - class = base_read(argv[1], base, &err); - func = base_read(argv[2], base, &err); - if(err) - return 1; - break; - case 2: - rmc_cmd = get_rmc_cmd(argv[1]); - if (rmc_cmd == NULL){ - ERROR("rmc '%s' not found\n",argv[1]); - return 1; - } - class = rmc_cmd->class; - func = rmc_cmd->func; - break; - default: - ERROR("Invalid number of parameters for rmc\n"); - return 1; - } - INFO("class:%d,func:%d\n",class,func); - tfp->esr=(unsigned long long) RMC<<26; - tfp->esr |= class; - tfp->esr |= (func<<8); - trap(tfp); - return 0; -} - -/* Separate buffer whitespace */ -void -tokenise(char* buff, char** argv, unsigned int* argc, char* sep) -{ - char* token; - - *argc=0; - token=strtok(buff,sep); - while(token!=NULL){ - argv[*argc]=token; - (*argc)++; - token=strtok(NULL,sep); - } - return; -} - -char* -trim(char* buff) -{ - int bufflen,i; - char* newbuff; - - newbuff = buff; - bufflen=strlen(buff); - - /* Trailing whitespace */ - for(i = bufflen-1; i>0; i--){ - if(buff[i]==' ' || buff[i]=='\t' || buff[i] == '\n'){ - buff[i]='\0';; - } - else{ - break; - } - } - /* Leading whitespace */ - for(i = 0; i<bufflen; i++){ - if(buff[i]==' ' || buff[i]=='\t' || buff[i] == '\n'){ - newbuff+=1; - } - else{ - break; - } - } - return newbuff; -} - -int -parse_cmd(char * cmd, struct trapframe* tfp) -{ - char* argv[MAX_PARTS]; - unsigned int argc; - const struct command* com; - - cmd = trim(cmd); - - /* Get array of strings by separating on whitespace */ - tokenise(cmd,argv,&argc," "); - - if(argc != 0){ - com = get_command(argv[0]); - } - - if(com == NULL){ - ERROR("Command '%s' not found\n",argv[0]); - return 1; - } - - /* Call eval function for specific command */ - com->eval(argv,argc, tfp); - return 0; -} - -int -main(int argc, char *argv[]) -{ - char buffer[BUFFER_SIZE]; - struct trapframe tf; - char* end; - - memset(&tf, 0, sizeof(struct trapframe)); - end=0; - do{ - printf("$ "); - fflush(stdout); - end = fgets(buffer,BUFFER_SIZE,stdin); - if(strlen(buffer)>1){ - parse_cmd(buffer,&tf); - } - fflush(stdout); - } - while(end != NULL); - return 0; -} diff --git a/arch/amd64/ram.c b/arch/amd64/ram.c @@ -3,5 +3,6 @@ int main(int argc, char *argv[]) { + debug(); return 0; } diff --git a/arch/amd64/rom.c b/arch/amd64/rom.c @@ -3,5 +3,6 @@ int main(int argc, char *argv[]) { + debug(); return 0; } diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile @@ -8,12 +8,14 @@ MORECFLAGS = -DUARTBASE=0x1c0c0000 \ ROMOBJS = rom-crt-$(SYS).o \ rom-$(SYS).o \ arch.o \ + $(DEBUGLANG) \ $(DRVDIR)/uart.o \ $(SRCDIR)/romfw/builtin.o \ RAMOBJS = ram-crt-$(SYS).o \ ram-$(SYS).o \ arch.o \ + $(DEBUGLANG) \ $(DRVDIR)/uart.o \ $(SRCDIR)/ramfw/builtin.o \ diff --git a/config/amd64-linux.mk b/config/amd64-linux.mk @@ -6,3 +6,4 @@ ASM = as LINKER = ld SYS = linux CROSS_COMPILE = +DEBUGLANG = $(SRCDIR)/debuglang/builtin.o diff --git a/include/rcode.h b/include/rcode.h @@ -149,6 +149,7 @@ extern void panic(const char *msg); extern void printk(const char * restrict fmt, ...) PRINTKFMT; extern void rmc(Rmucmd *cmd); extern void swtch(struct trapframe *fp); +extern void debug(void); /* architectural functions */ extern void halt(void); diff --git a/scripts/genhosted.sh b/scripts/gendebuglang.sh diff --git a/src/Makefile b/src/Makefile @@ -3,7 +3,7 @@ include $(PROJECTDIR)/scripts/rules.mk LIBS = libc librmu libtypes libhdl IMGS = ramfw romfw -DIRS = $(LIBS) $(IMGS) +DIRS = $(LIBS) $(IMGS) debuglang OBJS = rmc.o ecstr.o all: $(IMGS) @@ -14,7 +14,7 @@ gen: FORCE ecstr.c: $(INCDIR)/rcode.h $(SCRIPTDIR)/genecstr.sh $(INCDIR)/rcode.h -$(IMGS): $(LIBS) $(OBJS) +$(IMGS): $(LIBS) $(OBJS) debuglang $(DIRS): FORCE +@cd $@ && $(MAKE) diff --git a/src/debuglang/Makefile b/src/debuglang/Makefile @@ -0,0 +1,18 @@ +PROJECTDIR=../.. +include $(PROJECTDIR)/scripts/rules.mk + +OBJS = debuglang.o +TARGET = builtin.o + +all: $(TARGET) + +builtin.o: $(OBJS) + $(LD) $(RCODE_LDFLAGS) -r -o $@ $(OBJS) + +debuglang.h: $(SCRIPTDIR)/rmu.cmd + $(SCRIPTDIR)/gendebuglang.sh $(SCRIPTDIR)/rmu.cmd > $@ + +debuglang.c: debuglang.h + +clean: + rm -f debuglang.h diff --git a/src/debuglang/debuglang.c b/src/debuglang/debuglang.c @@ -0,0 +1,336 @@ +#include <errno.h> +#include <setjmp.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <rcode.h> + +#include "debuglang.h" + +void +print_tf(struct trapframe *tfp) +{ + printf("x0=0x%llx\tx1=0x%llx\tx2=0x%llx\tx3=0x%llx\n" + "x4=0x%llx\tx5=0x%llx\tx6=0x%llx\tx7=0x%llx\n" + "x8=0x%llx\tx9=0x%llx\tx10=0x%llx\tx11=0x%llx\n" + "x12=0x%llx\tx13=0x%llx\tx14=0x%llx\tx15=0x%llx\n" + "x16=0x%llx\tx17=0x%llx\tx18=0x%llx\tx19=0x%llx\n" + "x20=0x%llx\tx21=0x%llx\tx22=0x%llx\tx23=0x%llx\n" + "x24=0x%llx\tx25=0x%llx\tx26=0x%llx\tx27=0x%llx\n" + "x28=0x%llx\tx29=0x%llx\tx30=0x%llx\telr=%p\n" + "spsr=0x%llx\tesr=0x%llx\tfar=0x%llx\n" + "sp=0x%p\n", + tfp->x0, tfp->x1, tfp->x2, tfp->x3, + tfp->x4, tfp->x5, tfp->x6, tfp->x7, + tfp->x8, tfp->x9, tfp->x10, tfp->x11, + tfp->x12, tfp->x13, tfp->x14, tfp->x15, + tfp->x16, tfp->x17, tfp->x18, tfp->x19, + tfp->x20, tfp->x21, tfp->x22, tfp->x23, + tfp->x24, tfp->x25, tfp->x26, tfp->x27, + tfp->x28, tfp->x29, tfp->x30, tfp->elr, + tfp->spsr, tfp->esr, tfp->far, tfp->sp); +} + +/* Read a value in a given base between 2 and 16 0 means default base; + * 10, unless the string begins with "0x" or "0b" + */ +unsigned long long +base_read(char* str, int base, int *err) +{ + unsigned long long val; + char *endptr; + + endptr = NULL; + errno = 0; + val = strtoull(str, &endptr, base); + if (str == endptr || errno != 0){ + ERROR("strtoull error with '%s' in base %d\n", str, base); + if(err != NULL) + *err = 1; + } + return val; +} + +/* Get reg struct for named reg */ +unsigned long long* +get_named_reg(char* name, struct trapframe* tfp) +{ + size_t i; + char *regptr; + + regptr=NULL; + for(i=0;i<NUM_NAMED_REGS;i++){ + if(strcmp(name,named_regs[i].name)==0){ + regptr = (char*) tfp; + regptr += named_regs[i].offset; + } + } + return (unsigned long long*) regptr; +} + +/* Get rmc_command struct for named rmc command */ +const struct rmc_command* +get_rmc_cmd(char* name) +{ + size_t i; + + for(i=0;i<NUM_RMC_COMMANDS;i++){ + if(strcmp(name,rmc_commands[i].name)==0){ + return &rmc_commands[i]; + } + } + return NULL; +} + +/* Get command struct for named command */ +const struct command* +get_command(char* name) +{ + size_t i; + + for(i=0;i<NUM_COMMANDS;i++){ + if(strcmp(name,commands[i].name)==0){ + return &commands[i]; + } + } + return NULL; +} + +int +do_set(char** argv,int argc, struct trapframe* tfp) +{ + unsigned long long *reg=NULL; + unsigned long long setval=0; + unsigned int base; + int err; + + err = 0; + + reg = get_named_reg(argv[1],tfp); + if( reg == NULL){ + ERROR("Register '%s' not found\n",argv[1]); + return 1; + } + + base = 0; + + switch(argc){ + case 4: + base = base_read(argv[3], 10, &err); + if(err) + return 1; + /* fallthrough */ + case 3: + setval = base_read(argv[2], base, &err); + if(err) + return 1; + break; + default: + ERROR("Invalid number of parameters for set\n"); + return 1; + } + INFO("set:0x%llx\n",setval); + *reg=setval; + return 0; +} + +int +do_read(char** argv,int argc, struct trapframe* tfp) +{ + unsigned long long* reg=NULL; + char* format_string; + + reg = get_named_reg(argv[1],tfp); + if(reg == NULL){ + ERROR("Register '%s' not found\n",argv[1]); + return 1; + } + + switch(argc){ + case 3: + switch(atoi(argv[2])){ + case 10: + format_string="%llu\n"; + break; + case 16: + format_string="%llx\n"; + break; + default: + ERROR("Unsupported base for read:%s\nsupported: 10,16\n", + argv[2]); + return 1; + } + break; + case 2: + format_string="%llu\n"; + break; + default: + ERROR("Invalid number of arguments for read\n"); + return 1; + } + printf(format_string,*reg); + return 0; +} + +int +do_dump(char** argv,int argc, struct trapframe* tfp) +{ + print_tf(tfp); + return 0; +} + +int +do_trap(char** argv,int argc, struct trapframe* tfp) +{ + trap(tfp); + return 0; +} + +int +do_rmc(char** argv,int argc, struct trapframe* tfp) +{ + unsigned char class; + unsigned char func; + unsigned int base; + const struct rmc_command *rmc_cmd; + int err; + + err = 0; + + base = 0; + switch(argc){ + case 4: + base = base_read(argv[3], 10, &err); + if(err) + return 1; + /* fallthrough */ + case 3: + class = base_read(argv[1], base, &err); + func = base_read(argv[2], base, &err); + if(err) + return 1; + break; + case 2: + rmc_cmd = get_rmc_cmd(argv[1]); + if (rmc_cmd == NULL){ + ERROR("rmc '%s' not found\n",argv[1]); + return 1; + } + class = rmc_cmd->class; + func = rmc_cmd->func; + break; + default: + ERROR("Invalid number of parameters for rmc\n"); + return 1; + } + INFO("class:%d,func:%d\n",class,func); + tfp->esr=(unsigned long long) RMC<<26; + tfp->esr |= class; + tfp->esr |= (func<<8); + trap(tfp); + return 0; +} + +/* Separate buffer whitespace */ +void +tokenise(char* buff, char** argv, unsigned int* argc, char* sep) +{ + char* token; + + *argc=0; + token=strtok(buff,sep); + while(token!=NULL){ + argv[*argc]=token; + (*argc)++; + token=strtok(NULL,sep); + } + return; +} + +char* +trim(char* buff) +{ + int bufflen,i; + char* newbuff; + + newbuff = buff; + bufflen=strlen(buff); + + /* Trailing whitespace */ + for(i = bufflen-1; i>0; i--){ + if(buff[i]==' ' || buff[i]=='\t' || buff[i] == '\n'){ + buff[i]='\0';; + } + else{ + break; + } + } + /* Leading whitespace */ + for(i = 0; i<bufflen; i++){ + if(buff[i]==' ' || buff[i]=='\t' || buff[i] == '\n'){ + newbuff+=1; + } + else{ + break; + } + } + return newbuff; +} + +int +parse_cmd(char * cmd, struct trapframe* tfp) +{ + char* argv[MAX_PARTS]; + unsigned int argc; + const struct command* com; + + cmd = trim(cmd); + + /* Get array of strings by separating on whitespace */ + tokenise(cmd,argv,&argc," "); + + if(argc != 0){ + com = get_command(argv[0]); + } + + if(com == NULL){ + ERROR("Command '%s' not found\n",argv[0]); + return 1; + } + + /* Call eval function for specific command */ + com->eval(argv,argc, tfp); + return 0; +} + +static void +run(struct trapframe *tf) +{ + char buffer[BUFFER_SIZE]; + char* end; + + end=0; + do{ + printf("$ "); + fflush(stdout); + end = fgets(buffer,BUFFER_SIZE,stdin); + if(strlen(buffer)>1){ + parse_cmd(buffer, tf); + } + fflush(stdout); + } + while(end != NULL); +} + +void +debug(void) +{ + struct trapframe tf; + extern jmp_buf recover; + + memset(&tf, 0, sizeof(struct trapframe)); + + setjmp(recover); + run(&tf); +}