Skip to content

Commit

Permalink
MIPS: Support Linux/MIPS for OpenWRT, #21
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed Oct 1, 2021
1 parent eddc70d commit 33abc69
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 19 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ The branch [srs](https://github.com/ossrs/state-threads/tree/srs) will be patche
- [x] System: Support utest by gtest and coverage by gcov/gocvr.
- [x] System: Only support for Linux and Darwin. [#19](https://github.com/ossrs/state-threads/issues/19), [srs#2188](https://github.com/ossrs/srs/issues/2188).
- [x] System: Improve the performance of timer. [9fe8cfe5b](https://github.com/ossrs/state-threads/commit/9fe8cfe5b1c9741a2e671a46215184f267fba400), [7879c2b](https://github.com/ossrs/state-threads/commit/7879c2b), [387cddb](https://github.com/ossrs/state-threads/commit/387cddb)
- [ ] Windows: Support Windows 64bits. [#20](https://github.com/ossrs/state-threads/issues/20).
- [ ] MIPS: Support Linux/MIPS for OpenWRT, [#21](https://github.com/ossrs/state-threads/issues/21).
- [x] Windows: Support Windows 64bits. [#20](https://github.com/ossrs/state-threads/issues/20).
- [x] MIPS: Support Linux/MIPS for OpenWRT, [#21](https://github.com/ossrs/state-threads/issues/21).
- [ ] System: Support Multiple Threads for Linux and Darwin. [#19](https://github.com/ossrs/state-threads/issues/19), [srs#2188](https://github.com/ossrs/srs/issues/2188).
- [ ] System: Support sendmmsg for UDP, [#12](https://github.com/ossrs/state-threads/issues/12).

Expand Down
15 changes: 6 additions & 9 deletions md.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,7 @@
(void) gettimeofday(&tv, NULL); \
return (tv.tv_sec * 1000000LL + tv.tv_usec)

#if defined(__mips__)
#define MD_INIT_CONTEXT(_thread, _sp, _main) \
ST_BEGIN_MACRO \
MD_SETJMP((_thread)->context); \
_thread->context[0].__jmpbuf[0].__pc = (__ptr_t) _main; \
_thread->context[0].__jmpbuf[0].__sp = _sp; \
ST_END_MACRO

#else /* Not mips */
#if 1

/*
* On linux, there are a few styles of jmpbuf format. These vary based
Expand Down Expand Up @@ -190,6 +182,11 @@
#error "ARM/Linux pre-glibc2 not supported yet"
#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */

#elif defined(__mips__)
/* https://github.com/ossrs/state-threads/issues/21 */
#define MD_USE_BUILTIN_SETJMP
#define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jb[0]))

#else
#error "Unknown CPU architecture"
#endif /* Cases with common MD_INIT_CONTEXT and different SP locations */
Expand Down
80 changes: 80 additions & 0 deletions md_linux.S
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,86 @@

/****************************************************************/










#elif defined(__mips__)

/****************************************************************/

/*
* Internal __jmp_buf layout
*/
#define JB_SP 0 /* Stack pointer */
#define JB_RA 11 /* Return address */
#define JB_GP 1 /* Global pointer */
#define JB_S0 3 /* S0-S7, Saved temporaries */
#define JB_S1 4 /* S0-S7, Saved temporaries */
#define JB_S2 5 /* S0-S7, Saved temporaries */
#define JB_S3 6 /* S0-S7, Saved temporaries */
#define JB_S4 7 /* S0-S7, Saved temporaries */
#define JB_S5 8 /* S0-S7, Saved temporaries */
#define JB_S6 9 /* S0-S7, Saved temporaries */
#define JB_S7 10 /* S0-S7, Saved temporaries */
#define JB_FP 2 /* FP/S8 Frame pointer */

.file "md_linux.S"
.text

/* _st_md_cxt_save(__jmp_buf env) */ /* The env is $a0, https://en.wikipedia.org/wiki/MIPS_architecture#Calling_conventions */
.globl _st_md_cxt_save
.type _st_md_cxt_save, %function
.align 2
_st_md_cxt_save:
sw $sp, 0($a0) /* Save sp to env[0], *(long*)($a0+0) =sp */
sw $ra, 4($a0) /* Save ra to env[1], *(long*)($a0+4)=ra, the return address, https://chortle.ccsu.edu/AssemblyTutorial/Chapter-26/ass26_4.html */
sw $gp, 8($a0) /* Save gp to env[2], *(long*)($a0+8) =gp */
sw $s0, 12($a0) /* Save s0 to env[3], *(long*)($a0+12)=s0 */
sw $s1, 16($a0) /* Save s1 to env[4], *(long*)($a0+16)=s1 */
sw $s2, 20($a0) /* Save s2 to env[5], *(long*)($a0+20)=s2 */
sw $s3, 24($a0) /* Save s3 to env[6], *(long*)($a0+24)=s3 */
sw $s4, 28($a0) /* Save s4 to env[7], *(long*)($a0+28)=s4 */
sw $s5, 32($a0) /* Save s5 to env[8], *(long*)($a0+32)=s5 */
sw $s6, 36($a0) /* Save s6 to env[9], *(long*)($a0+36)=s6 */
sw $s7, 40($a0) /* Save s7 to env[10], *(long*)($a0+40)=s7 */
sw $fp, 44($a0) /* Save fp to env[11], *(long*)($a0+44) =fp */
li $v0, 0 /* Set return value to 0 */
jr $ra /* Return */

.size _st_md_cxt_save, .-_st_md_cxt_save

/****************************************************************/

/* _st_md_cxt_restore(__jmp_buf env, int val) */
.globl _st_md_cxt_restore
.type _st_md_cxt_restore, %function
.align 2
_st_md_cxt_restore:
lw $sp, 0($a0) /* Load sp from env[0], sp=*(long*)($a0+0) */
lw $ra, 4($a0) /* Load sp from env[1], ra=*(long*)($a0+4), the saved return address */
lw $gp, 8($a0) /* Load sp from env[2], gp=*(long*)($a0+8) */
lw $s0, 12($a0) /* Load sp from env[3], s0=*(long*)($a0+12) */
lw $s1, 16($a0) /* Load sp from env[4], s1=*(long*)($a0+16) */
lw $s2, 20($a0) /* Load sp from env[5], s2=*(long*)($a0+20) */
lw $s3, 24($a0) /* Load sp from env[6], s3=*(long*)($a0+24) */
lw $s4, 28($a0) /* Load sp from env[7], s4=*(long*)($a0+28) */
lw $s5, 32($a0) /* Load sp from env[8], s5=*(long*)($a0+32) */
lw $s6, 36($a0) /* Load sp from env[9], s6=*(long*)($a0+36) */
lw $s7, 40($a0) /* Load sp from env[10], s7=*(long*)($a0+40) */
lw $fp, 44($a0) /* Load sp from env[2], fp=*(long*)($a0+44) */
li $v0, 1 /* Set return value to 1 */
jr $ra /* Return to the saved return address */

.size _st_md_cxt_restore, .-_st_md_cxt_restore

/****************************************************************/

#endif

#endif
1 change: 1 addition & 0 deletions tools/helloworld/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
helloworld
11 changes: 11 additions & 0 deletions tools/helloworld/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.PHONY: clean

LDLIBS=../../obj/libst.a
CFLAGS=-g -O0 -I../../obj

./helloworld: helloworld.c $(LDLIBS)
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -o helloworld helloworld.c $(LDLIBS)

clean:
rm -f helloworld

20 changes: 20 additions & 0 deletions tools/helloworld/helloworld.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: MIT */
/* Copyright (c) 2021 Winlin */

#include <stdio.h>

#include <st.h>

int main(int argc, char** argv)
{
st_set_eventsys(ST_EVENTSYS_ALT);
st_init();

for (int i = 0; i < 10000; i++) {
printf("#%03d, Hello, state-threads world!\n", i);
st_sleep(1);
}

return 0;
}

27 changes: 24 additions & 3 deletions tools/porting/porting.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <stdio.h>
#include <setjmp.h>

int foo_return_zero();
int foo_return_one();
extern void print_buf(unsigned char* p, int nn_jb);
extern void print_jmpbuf();

Expand Down Expand Up @@ -37,17 +39,33 @@ int main(int argc, char** argv)
printf("sizeof(__ptr_t)=%d\n", sizeof(__ptr_t));
#endif

printf("\nReturn value:\n");
int r0 = foo_return_zero();
int r1 = foo_return_one();
printf("foo_return_zero=%d, foo_return_one=%d\n", r0, r1);

printf("\nCalling conventions:\n");
print_jmpbuf();

return 0;
}

int foo_return_zero()
{
return 0;
}

int foo_return_one()
{
return 1;
}

#ifdef __linux__
#ifdef __mips__
void print_jmpbuf()
{
// https://en.wikipedia.org/wiki/MIPS_architecture#Calling_conventions
register void* ra asm("ra");
register void* gp asm("gp");
register void* sp asm("sp");
register void* fp asm("fp");
Expand All @@ -60,8 +78,6 @@ void print_jmpbuf()
register void* s5 asm("s5");
register void* s6 asm("s6");
register void* s7 asm("s7");
printf("gp=%p, fp=%p, sp=%p, s0=%p, s1=%p, s2=%p, s3=%p, s4=%p, s5=%p, s6=%p, s7=%p\n",
gp, fp, sp, s0, s1, s2, s3, s4, s5, s6, s7);

/*
typedef unsigned long long __jmp_buf[13];
Expand All @@ -72,7 +88,12 @@ void print_jmpbuf()
} jmp_buf[1];
*/
jmp_buf ctx = {0};
setjmp(ctx);
if (!setjmp(ctx)) {
longjmp(ctx, 1);
}

printf("ra=%p, sp=%p, s0=%p, s1=%p, s2=%p, s3=%p, s4=%p, s5=%p, s6=%p, s7=%p, fp=%p, gp=%p\n",
ra, sp, s0, s1, s2, s3, s4, s5, s6, s7, fp, gp);

int nn_jb = sizeof(ctx[0].__jb);
printf("sizeof(jmp_buf)=%d (unsigned long long [%d])\n", nn_jb, nn_jb/8);
Expand Down
4 changes: 2 additions & 2 deletions tools/verify/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
LDLIBS=../../obj/libst.a
CFLAGS=-g -O0

./verify: verify.c
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -o $@ $^ $(LDLIBS)
./verify: verify.c $(LDLIBS)
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -o verify verify.c $(LDLIBS)

clean:
rm -f verify
Expand Down
11 changes: 8 additions & 3 deletions tools/verify/verify.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ int main(int argc, char** argv)
void verify_jmpbuf()
{
// https://en.wikipedia.org/wiki/MIPS_architecture#Calling_conventions
register void* ra asm("ra");
register void* gp asm("gp");
register void* sp asm("sp");
register void* fp asm("fp");
Expand All @@ -33,11 +34,15 @@ void verify_jmpbuf()
register void* s5 asm("s5");
register void* s6 asm("s6");
register void* s7 asm("s7");
printf("gp=%p, fp=%p, sp=%p, s0=%p, s1=%p, s2=%p, s3=%p, s4=%p, s5=%p, s6=%p, s7=%p\n",
gp, fp, sp, s0, s1, s2, s3, s4, s5, s6, s7);

jmp_buf ctx = {0};
_st_md_cxt_save(ctx);
int r0 = _st_md_cxt_save(ctx);
if (!r0) {
_st_md_cxt_restore(ctx, 1); // Restore/Jump to previous line, set r0 to 1.
}

printf("sp=%p, ra=%p, gp=%p, s0=%p, s1=%p, s2=%p, s3=%p, s4=%p, s5=%p, s6=%p, s7=%p, fp=%p\n",
sp, ra, gp, s0, s1, s2, s3, s4, s5, s6, s7, fp);

int nn_jb = sizeof(ctx[0].__jb);
unsigned char* p = (unsigned char*)ctx[0].__jb;
Expand Down

0 comments on commit 33abc69

Please sign in to comment.