git://scm.lunaixsky.com
/
lunaix-os.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
de33434
)
feat: add support for process to conduct Intel x87 and MMX related task.
author
Minep
<zelong56@gmail.com>
Sat, 17 Sep 2022 17:25:59 +0000
(18:25 +0100)
committer
Minep
<zelong56@gmail.com>
Sat, 17 Sep 2022 17:25:59 +0000
(18:25 +0100)
lunaix-os/arch/x86/boot.S
patch
|
blob
|
history
lunaix-os/includes/lunaix/process.h
patch
|
blob
|
history
lunaix-os/kernel/asm/x86/interrupt.S
patch
|
blob
|
history
lunaix-os/kernel/process/sched.c
patch
|
blob
|
history
lunaix-os/kernel/process/signal.c
patch
|
blob
|
history
diff --git
a/lunaix-os/arch/x86/boot.S
b/lunaix-os/arch/x86/boot.S
index 9c86bbc6bed8081695dcb00a58b33b100403b73e..938db876514333b8a8f0dec1b1d598590b51f80d 100644
(file)
--- a/
lunaix-os/arch/x86/boot.S
+++ b/
lunaix-os/arch/x86/boot.S
@@
-77,11
+77,17
@@
andl $0xfffff000, %eax # 有点多余,但写上还算明白一点
movl %eax, %cr3
andl $0xfffff000, %eax # 有点多余,但写上还算明白一点
movl %eax, %cr3
- /* 开启分页与地址转换 (CR0.PG=1, PG.WP=1) */
movl %cr0, %eax
movl %cr0, %eax
- orl $0x80010000, %eax
+ orl $0x80010000, %eax /* 开启分页与地址转换 (CR0.PG=1, CR0.WP=1) */
+ andl $0xfffffffb, %eax
+ orl $0x2, %eax /* 启用x87 FPU (CR0.MP=1, CR0.EM=0) */
movl %eax, %cr0
movl %eax, %cr0
+ movl %cr4, %eax
+ orl $0x600, %eax
+ movl %eax, %cr4 /* CR4.OSFXSR=1, CR4.OSXMMEXCPT=1 */
+ /* x87 FPU 已配置 */
+
addl $16, %esp
/* 进入高半核! */
addl $16, %esp
/* 进入高半核! */
diff --git
a/lunaix-os/includes/lunaix/process.h
b/lunaix-os/includes/lunaix/process.h
index c7b925ef59651532d3da80ab6a6f0fbc68fe0f28..c014443089bb557b35991bb7f1968c3873123a7b 100644
(file)
--- a/
lunaix-os/includes/lunaix/process.h
+++ b/
lunaix-os/includes/lunaix/process.h
@@
-31,14
+31,18
@@
struct proc_mm
struct mm_region regions;
};
struct mm_region regions;
};
+struct proc_sigstate
+{
+ isr_param proc_regs;
+ char fxstate[512] __attribute__((aligned(16)));
+};
+
struct proc_sig
{
void* signal_handler;
int sig_num;
struct proc_sig
{
void* signal_handler;
int sig_num;
- isr_param prev_context;
-};
-
-#define PROC_SIG_SIZE sizeof(struct proc_sig) // size=84
+ struct proc_sigstate prev_context;
+} __attribute__((packed));
struct proc_info
{
struct proc_info
{
@@
-50,11
+54,12
@@
struct proc_info
/* ---- critical section start ---- */
/* ---- critical section start ---- */
- pid_t pid;
- struct proc_info* parent;
- isr_param intr_ctx; // size=76
- uintptr_t ustack_top;
- void* page_table;
+ pid_t pid; // offset = 0
+ struct proc_info* parent; // offset = 4
+ isr_param intr_ctx; // offset = 8
+ uintptr_t ustack_top; // offset = 84
+ void* page_table; // offset = 88
+ void* fxstate; // offset = 92
/* ---- critical section end ---- */
/* ---- critical section end ---- */
diff --git
a/lunaix-os/kernel/asm/x86/interrupt.S
b/lunaix-os/kernel/asm/x86/interrupt.S
index 17236f8f9fb4805d67cb6b9bbb9e875f5d6ab190..14bafb68263a87826888c70ae3adbf5f7d2d8594 100644
(file)
--- a/
lunaix-os/kernel/asm/x86/interrupt.S
+++ b/
lunaix-os/kernel/asm/x86/interrupt.S
@@
-74,7
+74,12
@@
# 保存用户栈顶指针。这是因为我们允许系统调用内进行上下文切换,而这样一来,我们就失去了用户栈的信息,
# 这样一来,就无法设置信号上下文。这主要是为了实现了pause()而做的准备
# 保存用户栈顶指针。这是因为我们允许系统调用内进行上下文切换,而这样一来,我们就失去了用户栈的信息,
# 这样一来,就无法设置信号上下文。这主要是为了实现了pause()而做的准备
- movl (__current), %eax
+ movl (__current), %eax
+
+ # 保存x87FPU的状态
+ movl 92(%eax), %ebx
+ fxsave (%ebx)
+
movl 68(%esp), %ebx # 取出esp
movl %ebx, 84(%eax) # 存入__current->ustack_top
movl 68(%esp), %ebx # 取出esp
movl %ebx, 84(%eax) # 存入__current->ustack_top
@@
-97,6
+102,9
@@
movl 56(%esp), %eax
movl %eax, (debug_resv + 4)
#endif
movl 56(%esp), %eax
movl %eax, (debug_resv + 4)
#endif
+ movl (__current), %eax
+ movl 92(%eax), %eax
+ fxrstor (%eax)
popl %eax
popl %ebx
popl %eax
popl %ebx
@@
-168,9
+176,9
@@
# 注意2:handle_signal在调用之前,须确保proc_sig已经写入用户栈!
leal 8(%eax), %ebx # arg1 in %eax: addr of proc_sig structure in user stack
# 注意2:handle_signal在调用之前,须确保proc_sig已经写入用户栈!
leal 8(%eax), %ebx # arg1 in %eax: addr of proc_sig structure in user stack
- pushl $UDATA_SEG # proc_sig->prev_context.ss
+ pushl $UDATA_SEG # proc_sig->prev_context.
proc_regs.
ss
pushl %eax # esp
pushl %eax # esp
- pushl 64(%ebx) # proc_sig->prev_context.eflags
+ pushl 64(%ebx) # proc_sig->prev_context.
proc_regs.
eflags
pushl $UCODE_SEG # cs
pushl $sig_wrapper # eip for sig wrapper
pushl $UCODE_SEG # cs
pushl $sig_wrapper # eip for sig wrapper
diff --git
a/lunaix-os/kernel/process/sched.c
b/lunaix-os/kernel/process/sched.c
index 3ee0e7666c32eafe97c3436ac1c2a9ccc103f64b..4e3f290c4ca61e36699988c9f77f899d567c3bf7 100644
(file)
--- a/
lunaix-os/kernel/process/sched.c
+++ b/
lunaix-os/kernel/process/sched.c
@@
-282,6
+282,8
@@
alloc_process()
proc->created = clock_systime();
proc->pgid = proc->pid;
proc->fdtable = vzalloc(sizeof(struct v_fdtable));
proc->created = clock_systime();
proc->pgid = proc->pid;
proc->fdtable = vzalloc(sizeof(struct v_fdtable));
+ proc->fxstate =
+ vzalloc_dma(512); // FXSAVE需要十六位对齐地址,使用DMA块(128位对齐)
llist_init_head(&proc->mm.regions.head);
llist_init_head(&proc->tasks);
llist_init_head(&proc->mm.regions.head);
llist_init_head(&proc->tasks);
@@
-349,6
+351,7
@@
destroy_process(pid_t pid)
}
vfree(proc->fdtable);
}
vfree(proc->fdtable);
+ vfree_dma(proc->fxstate);
struct mm_region *pos, *n;
llist_for_each(pos, n, &proc->mm.regions.head, head)
struct mm_region *pos, *n;
llist_for_each(pos, n, &proc->mm.regions.head, head)
diff --git
a/lunaix-os/kernel/process/signal.c
b/lunaix-os/kernel/process/signal.c
index 5d09d9b6efa59bb02df9faabb3d0c7111d5ce9d2..9a9a34999dc86b19bf461b713c897b13357424c2 100644
(file)
--- a/
lunaix-os/kernel/process/signal.c
+++ b/
lunaix-os/kernel/process/signal.c
@@
-1,3
+1,4
@@
+#include <klibc/string.h>
#include <lunaix/lunistd.h>
#include <lunaix/lxsignal.h>
#include <lunaix/process.h>
#include <lunaix/lunistd.h>
#include <lunaix/lxsignal.h>
#include <lunaix/process.h>
@@
-22,7
+23,7
@@
void* default_handlers[_SIG_NUM] = {
[_SIGINT] = default_sighandler_term,
};
[_SIGINT] = default_sighandler_term,
};
-volatile
isr_param
__temp_save;
+volatile
struct proc_sigstate
__temp_save;
// Referenced in kernel/asm/x86/interrupt.S
void*
signal_dispatch()
// Referenced in kernel/asm/x86/interrupt.S
void*
signal_dispatch()
@@
-79,7
+80,9
@@
signal_dispatch()
解决办法就是先吧intr_ctx拷贝到一个静态分配的区域里,然后再注入到用户栈。
*/
解决办法就是先吧intr_ctx拷贝到一个静态分配的区域里,然后再注入到用户栈。
*/
- __temp_save = __current->intr_ctx;
+ __temp_save.proc_regs = __current->intr_ctx;
+ memcpy(__temp_save.fxstate, __current->fxstate, 512);
+
sig_ctx->prev_context = __temp_save;
sig_ctx->sig_num = sig_selected;
sig_ctx->prev_context = __temp_save;
sig_ctx->sig_num = sig_selected;
@@
-138,7
+141,8
@@
send_single:
__DEFINE_LXSYSCALL1(int, sigreturn, struct proc_sig, *sig_ctx)
{
__DEFINE_LXSYSCALL1(int, sigreturn, struct proc_sig, *sig_ctx)
{
- __current->intr_ctx = sig_ctx->prev_context;
+ memcpy(__current->fxstate, sig_ctx->prev_context.fxstate, 512);
+ __current->intr_ctx = sig_ctx->prev_context.proc_regs;
__current->flags &= ~PROC_FINPAUSE;
__SIGCLEAR(__current->sig_inprogress, sig_ctx->sig_num);
schedule();
__current->flags &= ~PROC_FINPAUSE;
__SIGCLEAR(__current->sig_inprogress, sig_ctx->sig_num);
schedule();