diff --git a/retrobsd.py b/retrobsd.py new file mode 100644 index 00000000..5c71efa4 --- /dev/null +++ b/retrobsd.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python3 +import os, sys, subprocess + +RISCV_MACHINE_MIN = ''' +#include "sys/param.h" +#include "sys/user.h" +#include "sys/proc.h" +int cmask = CMASK; + +int securelevel = -1; + +struct user u = {}; +void _start(){ + struct proc *p; + p = &proc[0]; + //p->p_addr = *ka6; + p->p_stat = SRUN; + p->p_flag |= SLOAD|SSYS; + p->p_nice = NZERO; + + u.u_procp = p; /* init user structure */ + //u.u_ap = u.u_arg; + u.u_cmask = cmask; + u.u_lastfile = -1; + +#ifdef INET + if (netoff = netinit()) + printf("netinit failed\n"); + else + { + NETSETHZ(); + NETSTART(); + } +#endif + +} +''' + + +def c2o(file, out='/tmp/c2o.o', includes=None, defines=None, opt='-O0', bits=64 ): + if 'fedora' in os.uname().nodename: + cmd = ['riscv64-linux-gnu-gcc'] + else: + cmd = ['riscv64-unknown-elf-gcc'] + + if bits==32: + cmd.append('-march=rv32imac') + cmd.append('-mabi=ilp32') + + cmd += [ + '-c', '-mcmodel=medany', '-fomit-frame-pointer', '-ffunction-sections', + '-ffreestanding', '-nostdlib', '-nostartfiles', '-nodefaultlibs', + opt, '-g', '-o', out, file + ] + if includes: + for inc in includes: + if not inc.startswith('-I'): inc = '-I'+inc + cmd.append(inc) + if defines: + for d in defines: + if not d.startswith('-D'): d = '-D'+d + cmd.append(d) + + print(cmd) + subprocess.check_call(cmd) + return out + + +def mkkernel(): + defines = [ + 'KERNEL', + 'CONS_MAJOR=UART_MAJOR', + ] + includes = [ + './include' + ] + obs = [] + + rtmp = '/tmp/_riscv_.c' + open(rtmp,'w').write(RISCV_MACHINE_MIN) + o = c2o( + rtmp, + out = '/tmp/_riscv_.o', + includes=includes, defines=defines, bits=32) + obs.append(o) + + + for name in os.listdir('./sys/kernel/'): + assert name.endswith('.c') + print(name) + o = c2o( + os.path.join('./sys/kernel', name), + out = '/tmp/%s.o' % name, + includes=includes, defines=defines, bits=32) + obs.append(o) + + macho = [] + #for name in 'machdep'.split(): + for name in 'devsw cons swap'.split(): + o = c2o( + './sys/pic32/%s.c' % name, + out = '/tmp/_riscv_%s.o' % name, + includes=includes, defines=defines, bits=32) + macho.append(o) + + + if 'fedora' in os.uname().nodename: + cmd = ['riscv64-linux-gnu-ld'] + else: + cmd = ['riscv64-unknown-elf-ld'] + + cmd += ['-march=rv32', '-m', 'elf32lriscv', '-o', '/tmp/retrobsd.elf'] + obs + macho + print(cmd) + subprocess.check_call(cmd) + +if __name__=='__main__': + mkkernel() diff --git a/sys/include/types.h b/sys/include/types.h index 30609226..f5496e2c 100644 --- a/sys/include/types.h +++ b/sys/include/types.h @@ -36,6 +36,16 @@ typedef struct label_t { unsigned val[12]; /* regs S0-S8, RA, GP and SP */ } label_t; #endif +#ifdef __riscv +typedef struct label_t { + unsigned val[33]; /* regs x0-x31, GP */ + #ifdef __riscv_f + unsigned fval[32]; /* regs f0-f31 */ + #endif +} label_t; +#endif + + typedef long daddr_t; typedef char * caddr_t; typedef u_int ino_t; diff --git a/sys/kernel/sys_pipe.c b/sys/kernel/sys_pipe.c index 7c380ba9..c82b4cec 100644 --- a/sys/kernel/sys_pipe.c +++ b/sys/kernel/sys_pipe.c @@ -294,7 +294,11 @@ pipe() /* Move a secondary return value to register $v1. */ u.u_frame [FRAME_R3] = u.u_rval; #else -#error "pipe return value for unknown architecture" + #ifdef __riscv + u.u_frame [FRAME_R3] = u.u_rval; + #else + #error "pipe return value for unknown architecture" + #endif #endif u.u_rval = r; wf->f_flag = FWRITE; diff --git a/sys/pic32/io.h b/sys/pic32/io.h index f3df65a7..6272522a 100644 --- a/sys/pic32/io.h +++ b/sys/pic32/io.h @@ -27,6 +27,10 @@ #ifdef PIC32MX7 # include "machine/pic32mx.h" #endif +#ifdef __riscv + #include "machine/riscv.h" +#endif + /* * Offsets of register values in saved context. @@ -97,9 +101,15 @@ unsigned ucall (int priority, void *address, int arg1, int arg2); static void inline __attribute__ ((always_inline)) mips_set_stack_pointer (void *x) { + #ifdef __riscv + asm volatile ( + "mv sp,a0" + : : "r" (x) : "sp"); + #else asm volatile ( "move $sp, %0" : : "r" (x) : "sp"); + #endif } /* @@ -109,10 +119,15 @@ static inline __attribute__ ((always_inline)) void *mips_get_stack_pointer () { void *x; - + #ifdef __riscv + asm volatile ( + "mv a0,sp" + : "=r" (x)); + #else asm volatile ( "move %0, $sp" : "=r" (x)); + #endif return x; } @@ -145,7 +160,14 @@ static int inline __attribute__ ((always_inline)) mips_intr_disable () { int status; + #ifdef __riscv + asm volatile ( + "csrr a0,mstatus\n" + "sfence.vma" + : "=r" (status)); + #else asm volatile ("di %0" : "=r" (status)); + #endif return status; } @@ -156,7 +178,11 @@ static void inline __attribute__ ((always_inline)) mips_intr_restore (int x) { /* C0_STATUS */ + #ifdef __riscv + asm volatile ("csrw mstatus,a0"); + #else mips_write_c0_register (12, 0, x); + #endif } /* @@ -165,7 +191,11 @@ mips_intr_restore (int x) static void inline __attribute__ ((always_inline)) mips_ehb() { + #ifdef __riscv + asm volatile ("fence"); + #else asm volatile ("ehb"); + #endif } /* @@ -175,7 +205,17 @@ static int inline __attribute__ ((always_inline)) mips_intr_enable () { int status; + #ifdef __riscv + asm volatile ( + "csrr a0, mstatus\n" + "sfence.vma\n" + "li a1, 0x0001\n" // Enable interrupts (SIE bit) + "or a0, a0,a1\n" + "csrw mstatus, a0" + : "=r" (status)); + #else asm volatile ("ei %0" : "=r" (status)); + #endif return status; } @@ -186,9 +226,16 @@ static int inline __attribute__ ((always_inline)) mips_clz (unsigned x) { int n; - + #ifdef __riscv + if (x != 0) { + while ((x & (1 << n)) == 0) { + n--; + } + } + #else asm volatile ("clz %0, %1" : "=r" (n) : "r" (x)); + #endif return n; } @@ -199,11 +246,32 @@ static unsigned inline __attribute__ ((always_inline)) mips_bswap (unsigned x) { int n; + #ifdef __riscv + asm volatile ( + "li t0, 0xff\n" // Load immediate with all ones + "sll t1, t0, 24\n" // Move all ones to the most significant byte + "srl t2, a0, 24\n" // Extract the most significant byte + "and t3, t1, t2\n" // Combine all ones with the most significant byte + "sra a0, a0, 24\n" // Shift the remaining bytes right by 24 bits + "ins a0, t3, 0, 8\n"// Insert the combined byte into the most significant position + "sll t1, t0, 8\n" // Move all ones to the second byte + "srl t2, a0, 16\n" // Extract the second byte + "and t3, t1, t2\n" // Combine all ones with the second byte + "sra a0, a0, 16\n" // Shift the remaining bytes right by 16 bits + "ins a0, t3, 8, 8\n" // Insert the combined byte into the second position + "sll t1, t0, 0\n" // Move all ones to the least significant byte + "srl t2, a0, 8\n" // Extract the least significant byte + "and t3, t1, t2\n" // Combine all ones with the least significant byte + "sra a0, a0, 8\n" // Shift the remaining byte right by 8 bits + "ins a0, t3, 16, 8" // Insert the combined byte into the least significant position + : "=r" (n) : "r" (x)); + #else asm volatile ( "wsbh %0, %1 \n" "rotr %0, 16" : "=r" (n) : "r" (x)); + #endif return n; } #endif /* __ASSEMBLER__ */ diff --git a/sys/pic32/riscv.h b/sys/pic32/riscv.h new file mode 100644 index 00000000..a0254a29 --- /dev/null +++ b/sys/pic32/riscv.h @@ -0,0 +1,20 @@ +#pragma once + +#define ST_RP 0x08000000 /* Enable reduced power mode */ +#define ST_UM 0x00000010 /* User mode */ + +// Peripheral registers. +#ifdef __ASSEMBLER__ +#define PIC32_R(a) (0xBF800000 + (a)) +#else +#define PIC32_R(a) *(volatile unsigned*)(0xBF800000 + (a)) +#endif + + +// Port A-G registers. +#define TRISA PIC32_R (0x86000) /* Port A: mask of inputs */ + +struct devspec { + unsigned _id; + const char *_name; +};