Skip to content

Commit

Permalink
Support __mips64 for MIPS 64 bits.
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed Aug 6, 2022
1 parent 8c8a0c5 commit a03a3c8
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 5 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ For Linux aarch64, which fail with `Unknown CPU architecture`:
make linux-debug EXTRA_CFLAGS="-D__aarch64__"
```

> Note: For more CPU architectures, please see [#22](https://github.com/ossrs/state-threads/issues/22)
Linux with valgrind:

```bash
Expand Down Expand Up @@ -110,6 +112,7 @@ The branch [srs](https://github.com/ossrs/state-threads/tree/srs) will be patche
- [x] LOONGARCH: Support loongarch for loongson CPU, [#24](https://github.com/ossrs/state-threads/issues/24).
- [x] 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).
- [x] RISCV: Support RISCV for RISCV CPU, [#24](https://github.com/ossrs/state-threads/pull/28).
- [x] MIPS: Support Linux/MIPS64 for loongson 3A4000/3B3000, [#21](https://github.com/ossrs/state-threads/pull/21).
- [ ] IDE: Support CLion for debugging and learning.
- [ ] System: Support sendmmsg for UDP, [#12](https://github.com/ossrs/state-threads/issues/12).

Expand Down
4 changes: 4 additions & 0 deletions md.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@
#error "ARM/Linux pre-glibc2 not supported yet"
#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */

#elif defined(__mips64)
/* https://github.com/ossrs/state-threads/issues/21 */
#define MD_USE_BUILTIN_SETJMP
#define MD_GET_SP(_t) *((long *)&((_t)->context[0].__jmpbuf[0]))
#elif defined(__mips__)
/* https://github.com/ossrs/state-threads/issues/21 */
#define MD_USE_BUILTIN_SETJMP
Expand Down
78 changes: 78 additions & 0 deletions md_linux.S
Original file line number Diff line number Diff line change
Expand Up @@ -433,9 +433,87 @@



#elif defined(__mips64)

/****************************************************************/
/* For MIPS64, see https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MIPS_Architecture_MIPS64_InstructionSet_%20AFP_P_MD00087_06.05.pdf */

/*
* 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:
sd $sp, 0($a0) /* Save sp to env[0], *(long*)($a0+ 0) =sp */
sd $ra, 8($a0) /* Save ra to env[1], *(long*)($a0+ 8)=ra, the return address, https://chortle.ccsu.edu/AssemblyTutorial/Chapter-26/ass26_4.html */
sd $gp, 16($a0) /* Save gp to env[2], *(long*)($a0+16) =gp */
sd $s0, 24($a0) /* Save s0 to env[3], *(long*)($a0+24)=s0 */
sd $s1, 32($a0) /* Save s1 to env[4], *(long*)($a0+32)=s1 */
sd $s2, 40($a0) /* Save s2 to env[5], *(long*)($a0+40)=s2 */
sd $s3, 48($a0) /* Save s3 to env[6], *(long*)($a0+48)=s3 */
sd $s4, 56($a0) /* Save s4 to env[7], *(long*)($a0+56)=s4 */
sd $s5, 64($a0) /* Save s5 to env[8], *(long*)($a0+64)=s5 */
sd $s6, 72($a0) /* Save s6 to env[9], *(long*)($a0+72)=s6 */
sd $s7, 80($a0) /* Save s7 to env[10], *(long*)($a0+80)=s7 */
sd $fp, 88($a0) /* Save fp to env[11], *(long*)($a0+88) =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:
ld $sp, 0($a0) /* Load sp from env[0], sp=*(long*)($a0+ 0) */
ld $ra, 8($a0) /* Load sp from env[1], ra=*(long*)($a0+ 8), the saved return address */
ld $gp, 16($a0) /* Load sp from env[2], gp=*(long*)($a0+16) */
ld $s0, 24($a0) /* Load sp from env[3], s0=*(long*)($a0+24) */
ld $s1, 32($a0) /* Load sp from env[4], s1=*(long*)($a0+32) */
ld $s2, 40($a0) /* Load sp from env[5], s2=*(long*)($a0+40) */
ld $s3, 48($a0) /* Load sp from env[6], s3=*(long*)($a0+48) */
ld $s4, 56($a0) /* Load sp from env[7], s4=*(long*)($a0+56) */
ld $s5, 64($a0) /* Load sp from env[8], s5=*(long*)($a0+64) */
ld $s6, 72($a0) /* Load sp from env[9], s6=*(long*)($a0+72) */
ld $s7, 80($a0) /* Load sp from env[10], s7=*(long*)($a0+80) */
ld $fp, 88($a0) /* Load sp from env[2], fp=*(long*)($a0+88) */
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

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






#elif defined(__mips__)

/****************************************************************/
/* For MIPS32, see https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00565-2B-MIPS32-QRC-01.01.pdf */

/*
* Internal __jmp_buf layout
Expand Down
3 changes: 2 additions & 1 deletion tools/helloworld/helloworld.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ int main(int argc, char** argv)
{
st_init();

for (int i = 0; i < 10000; i++) {
int i;
for (i = 0; i < 10000; i++) {
printf("#%03d, Hello, state-threads world!\n", i);
st_sleep(1);
}
Expand Down
3 changes: 3 additions & 0 deletions tools/jmpbuf/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
jmpbuf
jmpbuf.E.c

15 changes: 15 additions & 0 deletions tools/jmpbuf/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.PHONY: default clean pre

CFLAGS=-g -O0

default: ./jmpbuf pre

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

pre: jmpbuf.c
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Wall -E -o jmpbuf.E.c $^ $(LDLIBS)

clean:
rm -f jmpbuf jmpbuf.E.c

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

#include <stdio.h>
#include <setjmp.h>

int main(int argc, char** argv)
{
jmp_buf ctx = {0};
int r0 = setjmp(ctx);

int nn_jb = sizeof(ctx);
printf("r0=%d, sizeof(jmp_buf)=%d (unsigned long long [%d])\n", r0, nn_jb, nn_jb/8);
return 0;
}

51 changes: 47 additions & 4 deletions tools/porting/porting.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@ int main(int argc, char** argv)
// https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00565-2B-MIPS32-QRC-01.01.pdf
printf("__mips__: %d, __mips: %d, _MIPSEL: %d\n", __mips__, __mips, _MIPSEL);
#endif
#ifdef __mips64
printf("__mips64: %d\n", __mips64);
#endif
#ifdef __x86_64__
printf("__x86_64__: %d\n", __x86_64__);
#endif
#ifdef __loongarch64
printf("__loongarch64 :%d\n", __loongarch64);
printf("__loongarch__: %d __loongarch64: %d\n", __loongarch__, __loongarch64);
#endif
#ifdef __riscv
printf("__riscv: %d\n", __riscv);
Expand Down Expand Up @@ -84,9 +87,48 @@ int foo_return_one_arg1(int r0)
#if defined(__riscv) || defined(__arm__) || defined(__aarch64__)
void print_jmpbuf() {
}
#endif
#elif __mips64
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");
// $s0–$s7 $16–$23 saved temporaries
register void* s0 asm("s0");
register void* s1 asm("s1");
register void* s2 asm("s2");
register void* s3 asm("s3");
register void* s4 asm("s4");
register void* s5 asm("s5");
register void* s6 asm("s6");
register void* s7 asm("s7");

#ifdef __mips__
/*
typedef unsigned long long __jmp_buf[13];
typedef struct __jmp_buf_tag {
__jmp_buf __jmpbuf;
int __mask_was_saved;
__sigset_t __saved_mask;
} jmp_buf[1];
*/
jmp_buf ctx = {0};
int r0 = setjmp(ctx);
if (!r0) {
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].__jmpbuf);
printf("sizeof(jmp_buf)=%d (unsigned long long [%d])\n", nn_jb, nn_jb/8);

unsigned char* p = (unsigned char*)ctx[0].__jmpbuf;
print_buf(p, nn_jb);
}
#elif __mips__
void print_jmpbuf()
{
// https://en.wikipedia.org/wiki/MIPS_architecture#Calling_conventions
Expand Down Expand Up @@ -207,7 +249,8 @@ void print_buf(unsigned char* p, int nn_jb)
{
printf(" ");

for (int i = 0; i < nn_jb; i++) {
int i;
for (i = 0; i < nn_jb; i++) {
printf("0x%02x ", (unsigned char)p[i]);

int newline = ((i + 1) % sizeof(void*));
Expand Down

0 comments on commit a03a3c8

Please sign in to comment.