Compare commits

...

5 Commits

Author SHA1 Message Date
Ariadne Conill 69ebc5e51b README: add or1k
continuous-integration/woodpecker the build was successful Details
2022-02-13 09:07:36 +00:00
Ariadne Conill 0a72eff002 or1k: add freestanding bits 2022-02-13 09:06:58 +00:00
Ariadne Conill 973e61441a or1k: add getcontext/setcontext/swapcontext 2022-02-13 08:58:38 +00:00
Ariadne Conill 00128f7575 or1k: add makecontext and trampoline 2022-02-13 08:58:03 +00:00
Ariadne Conill 7fc08a6dc6 or1k: add definitions 2022-02-13 08:57:36 +00:00
8 changed files with 270 additions and 0 deletions

View File

@ -24,6 +24,7 @@ target to do it.
| m68k | ✓ | | ✓ | ✓ |
| mips | ✓ | | ✓ | |
| mips64 | ✓ | | ✓ | |
| or1k | ✓ | | ✓ | ✓ |
| ppc | ✓ | ✓ | | |
| ppc64 | ✓ | ✓ | | |
| riscv32 | ✓ | | ✓ | ✓ |

22
arch/or1k/defs.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef __ARCH_OR1K_DEFS_H
#define __ARCH_OR1K_DEFS_H
#define REG_SZ (4)
#define MCONTEXT_GREGS (20)
#define REG_SP (1)
#define REG_FP (2)
#define REG_RA (9)
#define REG_SA (11)
#define REG_LR (14)
#define REG_PC (33)
#define REG_SR (34)
#define PC_OFFSET REG_OFFSET(REG_PC)
#define FETCH_LINKPTR(dest) \
asm("l.ori %0, r14, 0" :: "r" ((dest)))
#include "common-defs.h"
#endif

39
arch/or1k/getcontext.S Normal file
View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2022 Ariadne Conill <ariadne@dereferenced.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* This software is provided 'as is' and without any warranty, express or
* implied. In no event shall the authors be liable for any damages arising
* from the use of this software.
*/
#include "defs.h"
ALIAS(getcontext, libucontext_getcontext)
ALIAS(__getcontext, libucontext_getcontext)
FUNC(libucontext_getcontext)
l.sw REG_OFFSET(1)(r3), r1 /* store r1 and r2 */
l.sw REG_OFFSET(2)(r3), r2
l.sw REG_OFFSET(9)(r3), r9 /* store r9 to both r9 and r11 in the context */
l.sw REG_OFFSET(11)(r3), r9
l.sw REG_OFFSET(10)(r3), r10 /* store r10 for TLS */
l.sw REG_OFFSET(14)(r3), r14 /* store r14 through r30 even */
l.sw REG_OFFSET(16)(r3), r16
l.sw REG_OFFSET(18)(r3), r18
l.sw REG_OFFSET(20)(r3), r20
l.sw REG_OFFSET(22)(r3), r22
l.sw REG_OFFSET(24)(r3), r24
l.sw REG_OFFSET(26)(r3), r26
l.sw REG_OFFSET(28)(r3), r28
l.sw REG_OFFSET(30)(r3), r30
l.jr r9
l.ori r11, r0, 0
END(libucontext_getcontext)

View File

@ -0,0 +1,28 @@
#ifndef LIBUCONTEXT_BITS_H
#define LIBUCONTEXT_BITS_H
typedef struct sigaltstack {
void *ss_sp;
int ss_flags;
size_t ss_size;
} libucontext_stack_t;
typedef int libucontext_greg_t, libucontext_gregset_t[32];
typedef struct {
struct {
libucontext_gregset_t gpr;
libucontext_greg_t pc;
libucontext_greg_t sr;
} regs;
unsigned long oldmask;
} libucontext_mcontext_t;
typedef struct libucontext_ucontext {
unsigned long uc_flags;
struct libucontext_ucontext *uc_link;
libucontext_stack_t uc_stack;
libucontext_mcontext_t uc_mcontext;
} libucontext_ucontext_t;
#endif

61
arch/or1k/makecontext.c Normal file
View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2022 Ariadne Conill <ariadne@dereferenced.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* This software is provided 'as is' and without any warranty, express or
* implied. In no event shall the authors be liable for any damages arising
* from the use of this software.
*/
#include <stddef.h>
#include <stdarg.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include "defs.h"
#include <libucontext/libucontext.h>
extern void libucontext_trampoline(void);
void
libucontext_makecontext(libucontext_ucontext_t *ucp, void (*func)(void), int argc, ...)
{
libucontext_greg_t *sp;
va_list va;
int i;
/* set up and align the stack. */
sp = (libucontext_greg_t *) ((uintptr_t) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size);
sp -= argc < 6 ? 0 : (argc - 6);
sp = (libucontext_greg_t *) (((uintptr_t) sp & ~0x3));
/* set up the ucontext structure */
ucp->uc_mcontext.regs.gpr[REG_SP] = (libucontext_greg_t) sp;
ucp->uc_mcontext.regs.gpr[REG_RA] = (libucontext_greg_t) &libucontext_trampoline;
ucp->uc_mcontext.regs.gpr[REG_FP] = 0;
ucp->uc_mcontext.regs.gpr[REG_SA] = (libucontext_greg_t) func;
ucp->uc_mcontext.regs.gpr[REG_LR] = (libucontext_greg_t) ucp->uc_link;
va_start(va, argc);
/* args less than argv[6] have dedicated registers, else they overflow onto stack */
for (i = 0; i < argc; i++)
{
if (i < 6)
ucp->uc_mcontext.regs.gpr[i + 3] = va_arg (va, libucontext_greg_t);
else
sp[i - 6] = va_arg (va, libucontext_greg_t);
}
va_end(va);
}
#ifdef EXPORT_UNPREFIXED
extern __typeof(libucontext_makecontext) makecontext __attribute__((weak, __alias__("libucontext_makecontext")));
extern __typeof(libucontext_makecontext) __makecontext __attribute__((weak, __alias__("libucontext_makecontext")));
#endif

48
arch/or1k/setcontext.S Normal file
View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2022 Ariadne Conill <ariadne@dereferenced.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* This software is provided 'as is' and without any warranty, express or
* implied. In no event shall the authors be liable for any damages arising
* from the use of this software.
*/
#include "defs.h"
ALIAS(setcontext, libucontext_setcontext)
ALIAS(__setcontext, libucontext_setcontext)
FUNC(libucontext_setcontext)
l.ori r30, r3, 0 /* avoid clobbering r3 by copying to r30 */
l.lwz r3, REG_OFFSET(3)(r30) /* restore r3-r8 (argument registers) */
l.lwz r4, REG_OFFSET(4)(r30)
l.lwz r5, REG_OFFSET(5)(r30)
l.lwz r6, REG_OFFSET(6)(r30)
l.lwz r7, REG_OFFSET(7)(r30)
l.lwz r8, REG_OFFSET(8)(r30)
l.lwz r1, REG_OFFSET(1)(r30) /* restore stack/frame pointers */
l.lwz r2, REG_OFFSET(2)(r30)
l.lwz r9, REG_OFFSET(9)(r30) /* restore link register and starting address register */
l.lwz r11, REG_OFFSET(11)(r30)
l.lwz r10, REG_OFFSET(10)(r30) /* restore TLS register */
l.lwz r14, REG_OFFSET(14)(r30) /* restore r14-r30, even only */
l.lwz r16, REG_OFFSET(16)(r30)
l.lwz r18, REG_OFFSET(18)(r30)
l.lwz r20, REG_OFFSET(20)(r30)
l.lwz r22, REG_OFFSET(22)(r30)
l.lwz r24, REG_OFFSET(24)(r30)
l.lwz r26, REG_OFFSET(26)(r30)
l.lwz r28, REG_OFFSET(28)(r30)
l.lwz r30, REG_OFFSET(30)(r30)
l.jr r11 /* jump to new starting address */
l.ori r11, r0, 0
END(libucontext_setcontext)

68
arch/or1k/swapcontext.S Normal file
View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2022 Ariadne Conill <ariadne@dereferenced.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* This software is provided 'as is' and without any warranty, express or
* implied. In no event shall the authors be liable for any damages arising
* from the use of this software.
*/
#include "defs.h"
ALIAS(swapcontext, libucontext_swapcontext)
ALIAS(__swapcontext, libucontext_swapcontext)
FUNC(libucontext_swapcontext)
/* copy context into r3 like getcontext */
l.sw REG_OFFSET(1)(r3), r1 /* store r1 and r2 */
l.sw REG_OFFSET(2)(r3), r2
l.sw REG_OFFSET(9)(r3), r9 /* store r9 to both r9 and r11 in the context */
l.sw REG_OFFSET(11)(r3), r9
l.sw REG_OFFSET(10)(r3), r10 /* store r10 for TLS */
l.sw REG_OFFSET(14)(r3), r14 /* store r14 through r30 even */
l.sw REG_OFFSET(16)(r3), r16
l.sw REG_OFFSET(18)(r3), r18
l.sw REG_OFFSET(20)(r3), r20
l.sw REG_OFFSET(22)(r3), r22
l.sw REG_OFFSET(24)(r3), r24
l.sw REG_OFFSET(26)(r3), r26
l.sw REG_OFFSET(28)(r3), r28
l.sw REG_OFFSET(30)(r3), r30
/* set the new context from r4 */
l.ori r30, r4, 0 /* copy r4 to r30 to avoid clobbering */
l.lwz r3, REG_OFFSET(3)(r30) /* restore r3-r8 (argument registers) */
l.lwz r4, REG_OFFSET(4)(r30)
l.lwz r5, REG_OFFSET(5)(r30)
l.lwz r6, REG_OFFSET(6)(r30)
l.lwz r7, REG_OFFSET(7)(r30)
l.lwz r8, REG_OFFSET(8)(r30)
l.lwz r1, REG_OFFSET(1)(r30) /* restore stack/frame pointers */
l.lwz r2, REG_OFFSET(2)(r30)
l.lwz r9, REG_OFFSET(9)(r30) /* restore link register and starting address register */
l.lwz r11, REG_OFFSET(11)(r30)
l.lwz r10, REG_OFFSET(10)(r30) /* restore TLS register */
l.lwz r14, REG_OFFSET(14)(r30) /* restore r14-r30, even only */
l.lwz r16, REG_OFFSET(16)(r30)
l.lwz r18, REG_OFFSET(18)(r30)
l.lwz r20, REG_OFFSET(20)(r30)
l.lwz r22, REG_OFFSET(22)(r30)
l.lwz r24, REG_OFFSET(24)(r30)
l.lwz r26, REG_OFFSET(26)(r30)
l.lwz r28, REG_OFFSET(28)(r30)
l.lwz r30, REG_OFFSET(30)(r30)
l.jr r11 /* jump to new starting address */
l.ori r11, r0, 0
END(libucontext_swapcontext)

3
arch/or1k/trampoline.c Normal file
View File

@ -0,0 +1,3 @@
#include "defs.h"
#include <libucontext/libucontext.h>
#include "common-trampoline.c"