Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Implementation of cpu_switchto(9) for the LatticeMico32 architecture

  • Loading branch information...
commit 0a6713fb5a7ab3003f6e263389bf056f25f32930 1 parent aa55d25
Yann Sionneau authored
View
18 sys/arch/lm32/include/asm.h
@@ -54,6 +54,14 @@
#endif
#define _ASM_LABEL(x) x
+#ifdef __STDC__
+# define __CONCAT(x,y) x ## y
+# define __STRING(x) #x
+#else
+# define __CONCAT(x,y) x/**/y
+# define __STRING(x) "x"
+#endif
+
/* let kernels and others override entrypoint alignment */
#ifndef _ALIGN_TEXT
# define _ALIGN_TEXT .align 2
@@ -92,7 +100,15 @@
#define NENTRY(y) _ENTRY(_C_LABEL(y))
#define ASENTRY(y) _ENTRY(_ASM_LABEL(y)) _PROF_PROLOGUE
-#define CPUVAR(off) _C_LABEL(cpu_info_store)+__CONCAT(CPU_INFO_,off)
+#define SET_CPUVAR(off,reg) \
+ mvhi r25, hi(_C_LABEL(cpu_info_store)) ; \
+ ori r25, r25, lo(_C_LABEL(cpu_info_store)) ; \
+ lw reg, (r25+__CONCAT(CPU_INFO_,off))
+
+#define GET_CPUVAR(reg,off) \
+ mvhi r25, hi(_C_LABEL(cpu_info_store)) ; \
+ ori r25, r25, lo(_C_LABEL(cpu_info_store)) ; \
+ sw (r25+__CONCAT(CPU_INFO_,off)), reg
#define SET_ENTRY_SIZE(y) \
.size _C_LABEL(y), . - _C_LABEL(y)
View
2  sys/arch/lm32/include/pcb.h
@@ -39,6 +39,8 @@
struct pcb {
struct pmap *pcb_pm; /* pmap of our vmspace */
register_t pcb_sp; /* saved SP */
+ register_t pcb_ra; /* saved RA */
+ register_t pcb_fp; /* saved FP */
int pcb_flags;
};
View
80 sys/arch/lm32/lm32/locore_subr.S
@@ -3,6 +3,7 @@
*/
#include <lm32/asm.h>
+#include "assym.h"
// TODO: implement suword
ENTRY(suword)
@@ -27,3 +28,82 @@ ENTRY(setjmp)
// TODO: implement longjmp
ENTRY(longjmp)
+
+/*
+ * struct lwp *cpu_switchto(struct lwp *oldlwp, struct *newlwp,
+ * bool returning)
+ *
+ * 1. if (oldlwp != NULL), save its context.
+ * 2. then, restore context of newlwp.
+ *
+ * Note that the stack frame layout is known to "struct switchframe" in
+ * <machine/frame.h> and to the code in cpu_lwp_fork() which initializes
+ * it for a new lwp.
+ * r1: oldlwp and return value
+ * r2: newlwp
+ * r3: returning
+ */
+ENTRY(cpu_switchto)
+ addi sp, sp, -16
+ sw (sp+0), fp
+ sw (sp+4), ra
+ sw (sp+8), r11
+ sw (sp+12), r12
+ ori fp, r0, 16
+ add fp, sp, sp
+
+ /* Save old context. */
+ lw r11, (r1+L_PCB)
+ sw (r11+PCB_SP), sp
+ sw (r11+PCB_FP), fp
+ sw (r11+PCB_RA), ra
+
+ /* Switch to newlwp's stack. */
+1: lw r12, (r2+L_PCB)
+ lw ra, (r12+PCB_RA)
+ lw fp, (r12+PCB_FP)
+ lw sp, (r12+PCB_SP)
+
+ /* Set curlwp. */
+ SET_CPUVAR(CURLWP,r12)
+
+ /* Skip the rest if returning to a pinned LWP. */
+ bne r3, r0, 4f /* branch if r3 != 0 */
+
+ /* Check if this process is using RAS (restartable atomic sequence). */
+ /* TODO: check for RAS */
+ lw r12, (r2+L_PROC)
+ lw r12, (r12+P_RASLIST)
+ bne r12, r0, 5f
+
+ /* Return to the new LWP, returning 'oldlwp' in r1. */
+4:
+ lw r12, (sp+12)
+ lw r11, (sp+8)
+ lw ra, (sp+4)
+ lw fp, (sp+0)
+ addi sp, sp, 16
+ ret
+
+ /* Check for restartable atomic sequence (RAS). */
+5:
+ sw (sp+0), r1
+ sw (sp+4), r2
+ addi sp, sp, 8
+ lw r2, (r2+(L_MD_REGS+MD_UTF+TF_REGS+R_PC))
+/* lw r2, (r2+MD_UTF)
+ lw r2, (r2+TF_REGS)
+ lw r2, (r2+R_PC)*/
+ lw r1, (sp+4)
+ lw r1, (r1+L_PROC)
+
+ /* call ras_lookup(newlwp->l_proc, newlwp.md_regs.md_utf.tf_regs.r_pc); */
+ calli _C_LABEL(ras_lookup)
+
+ /* save return value in tf_regs.r_pc */
+ sw (r2+R_PC), r1
+
+ lw r2, (sp+4)
+ lw r1, (sp+0)
+ addi sp, sp, -8
+ bi 4b
View
16 sys/arch/milkymist/milkymist/genassym.cf
@@ -35,8 +35,10 @@
include <machine/pte.h>
include <machine/vmparam.h>
include <machine/types.h>
+include <machine/pcb.h>
include <sys/cpu.h>
#include <sys/lwp.h>
+include <sys/proc.h>
# general constants
define PAGE_SIZE PAGE_SIZE
@@ -51,6 +53,20 @@ define PG_FRAME PG_FRAME
define CPU_INFO_SELF offsetof(struct cpu_info, ci_self)
define CPU_INFO_CURLWP offsetof(struct cpu_info, ci_curlwp)
+define PCB_RA offsetof(struct pcb, pcb_ra)
+define PCB_FP offsetof(struct pcb, pcb_fp)
+define PCB_SP offsetof(struct pcb, pcb_sp)
define L_NOPREEMPT offsetof(struct lwp, l_nopreempt)
define L_DOPREEMPT offsetof(struct lwp, l_dopreempt)
+define L_PCB offsetof(struct lwp, l_addr)
+define L_MD_REGS offsetof(struct lwp, l_md)
+define L_PROC offsetof(struct lwp, l_proc)
+
+define MD_UTF offsetof(struct mdlwp, md_utf)
+
+define TF_REGS offsetof(struct trapframe, tf_regs)
+
+define R_PC offsetof(struct reg, r_pc)
+
+define P_RASLIST offsetof(struct proc, p_raslist)
Please sign in to comment.
Something went wrong with that request. Please try again.