mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-19 20:34:20 +08:00
C6X: process management
Original port to early 2.6 kernel using TI COFF toolchain. Brought up to date by Mark Salter <msalter@redhat.com> Signed-off-by: Aurelien Jacquiot <a-jacquiot@ti.com> Signed-off-by: Mark Salter <msalter@redhat.com> Acked-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
parent
14aa7e8bf6
commit
687b12baec
132
arch/c6x/include/asm/processor.h
Normal file
132
arch/c6x/include/asm/processor.h
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Port on Texas Instruments TMS320C6x architecture
|
||||
*
|
||||
* Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
|
||||
* Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
|
||||
*
|
||||
* Updated for 2.6.34: Mark Salter <msalter@redhat.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#ifndef _ASM_C6X_PROCESSOR_H
|
||||
#define _ASM_C6X_PROCESSOR_H
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/current.h>
|
||||
|
||||
/*
|
||||
* Default implementation of macro that returns current
|
||||
* instruction pointer ("program counter").
|
||||
*/
|
||||
#define current_text_addr() \
|
||||
({ \
|
||||
void *__pc; \
|
||||
asm("mvc .S2 pce1,%0\n" : "=b"(__pc)); \
|
||||
__pc; \
|
||||
})
|
||||
|
||||
/*
|
||||
* User space process size. This is mostly meaningless for NOMMU
|
||||
* but some C6X processors may have RAM addresses up to 0xFFFFFFFF.
|
||||
* Since calls like mmap() can return an address or an error, we
|
||||
* have to allow room for error returns when code does something
|
||||
* like:
|
||||
*
|
||||
* addr = do_mmap(...)
|
||||
* if ((unsigned long)addr >= TASK_SIZE)
|
||||
* ... its an error code, not an address ...
|
||||
*
|
||||
* Here, we allow for 4096 error codes which means we really can't
|
||||
* use the last 4K page on systems with RAM extending all the way
|
||||
* to the end of the 32-bit address space.
|
||||
*/
|
||||
#define TASK_SIZE 0xFFFFF000
|
||||
|
||||
/*
|
||||
* This decides where the kernel will search for a free chunk of vm
|
||||
* space during mmap's. We won't be using it
|
||||
*/
|
||||
#define TASK_UNMAPPED_BASE 0
|
||||
|
||||
struct thread_struct {
|
||||
unsigned long long b15_14;
|
||||
unsigned long long a15_14;
|
||||
unsigned long long b13_12;
|
||||
unsigned long long a13_12;
|
||||
unsigned long long b11_10;
|
||||
unsigned long long a11_10;
|
||||
unsigned long long ricl_icl;
|
||||
unsigned long usp; /* user stack pointer */
|
||||
unsigned long pc; /* kernel pc */
|
||||
unsigned long wchan;
|
||||
};
|
||||
|
||||
#define INIT_THREAD \
|
||||
{ \
|
||||
.usp = 0, \
|
||||
.wchan = 0, \
|
||||
}
|
||||
|
||||
#define INIT_MMAP { \
|
||||
&init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, \
|
||||
NULL, NULL }
|
||||
|
||||
#define task_pt_regs(task) \
|
||||
((struct pt_regs *)(THREAD_START_SP + task_stack_page(task)) - 1)
|
||||
|
||||
#define alloc_kernel_stack() __get_free_page(GFP_KERNEL)
|
||||
#define free_kernel_stack(page) free_page((page))
|
||||
|
||||
|
||||
/* Forward declaration, a strange C thing */
|
||||
struct task_struct;
|
||||
|
||||
extern void start_thread(struct pt_regs *regs, unsigned int pc,
|
||||
unsigned long usp);
|
||||
|
||||
/* Free all resources held by a thread. */
|
||||
static inline void release_thread(struct task_struct *dead_task)
|
||||
{
|
||||
}
|
||||
|
||||
/* Prepare to copy thread state - unlazy all lazy status */
|
||||
#define prepare_to_copy(tsk) do { } while (0)
|
||||
|
||||
extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
|
||||
|
||||
#define copy_segments(tsk, mm) do { } while (0)
|
||||
#define release_segments(mm) do { } while (0)
|
||||
|
||||
/*
|
||||
* saved PC of a blocked thread.
|
||||
*/
|
||||
#define thread_saved_pc(tsk) (task_pt_regs(tsk)->pc)
|
||||
|
||||
/*
|
||||
* saved kernel SP and DP of a blocked thread.
|
||||
*/
|
||||
#ifdef _BIG_ENDIAN
|
||||
#define thread_saved_ksp(tsk) \
|
||||
(*(unsigned long *)&(tsk)->thread.b15_14)
|
||||
#define thread_saved_dp(tsk) \
|
||||
(*(((unsigned long *)&(tsk)->thread.b15_14) + 1))
|
||||
#else
|
||||
#define thread_saved_ksp(tsk) \
|
||||
(*(((unsigned long *)&(tsk)->thread.b15_14) + 1))
|
||||
#define thread_saved_dp(tsk) \
|
||||
(*(unsigned long *)&(tsk)->thread.b15_14)
|
||||
#endif
|
||||
|
||||
extern unsigned long get_wchan(struct task_struct *p);
|
||||
|
||||
#define KSTK_EIP(tsk) (task_pt_regs(task)->pc)
|
||||
#define KSTK_ESP(tsk) (task_pt_regs(task)->sp)
|
||||
|
||||
#define cpu_relax() do { } while (0)
|
||||
|
||||
extern const struct seq_operations cpuinfo_op;
|
||||
|
||||
#endif /* ASM_C6X_PROCESSOR_H */
|
121
arch/c6x/include/asm/thread_info.h
Normal file
121
arch/c6x/include/asm/thread_info.h
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Port on Texas Instruments TMS320C6x architecture
|
||||
*
|
||||
* Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
|
||||
* Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
|
||||
*
|
||||
* Updated for 2.6.3x: Mark Salter <msalter@redhat.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#ifndef _ASM_C6X_THREAD_INFO_H
|
||||
#define _ASM_C6X_THREAD_INFO_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <asm/page.h>
|
||||
|
||||
#ifdef CONFIG_4KSTACKS
|
||||
#define THREAD_SIZE 4096
|
||||
#define THREAD_SHIFT 12
|
||||
#define THREAD_ORDER 0
|
||||
#else
|
||||
#define THREAD_SIZE 8192
|
||||
#define THREAD_SHIFT 13
|
||||
#define THREAD_ORDER 1
|
||||
#endif
|
||||
|
||||
#define THREAD_START_SP (THREAD_SIZE - 8)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
typedef struct {
|
||||
unsigned long seg;
|
||||
} mm_segment_t;
|
||||
|
||||
/*
|
||||
* low level task data.
|
||||
*/
|
||||
struct thread_info {
|
||||
struct task_struct *task; /* main task structure */
|
||||
struct exec_domain *exec_domain; /* execution domain */
|
||||
unsigned long flags; /* low level flags */
|
||||
int cpu; /* cpu we're on */
|
||||
int preempt_count; /* 0 = preemptable, <0 = BUG */
|
||||
mm_segment_t addr_limit; /* thread address space */
|
||||
struct restart_block restart_block;
|
||||
};
|
||||
|
||||
/*
|
||||
* macros/functions for gaining access to the thread information structure
|
||||
*
|
||||
* preempt_count needs to be 1 initially, until the scheduler is functional.
|
||||
*/
|
||||
#define INIT_THREAD_INFO(tsk) \
|
||||
{ \
|
||||
.task = &tsk, \
|
||||
.exec_domain = &default_exec_domain, \
|
||||
.flags = 0, \
|
||||
.cpu = 0, \
|
||||
.preempt_count = INIT_PREEMPT_COUNT, \
|
||||
.addr_limit = KERNEL_DS, \
|
||||
.restart_block = { \
|
||||
.fn = do_no_restart_syscall, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define init_thread_info (init_thread_union.thread_info)
|
||||
#define init_stack (init_thread_union.stack)
|
||||
|
||||
/* get the thread information struct of current task */
|
||||
static inline __attribute__((const))
|
||||
struct thread_info *current_thread_info(void)
|
||||
{
|
||||
struct thread_info *ti;
|
||||
asm volatile (" clr .s2 B15,0,%1,%0\n"
|
||||
: "=b" (ti)
|
||||
: "Iu5" (THREAD_SHIFT - 1));
|
||||
return ti;
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
|
||||
|
||||
/* thread information allocation */
|
||||
#ifdef CONFIG_DEBUG_STACK_USAGE
|
||||
#define THREAD_FLAGS (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO)
|
||||
#else
|
||||
#define THREAD_FLAGS (GFP_KERNEL | __GFP_NOTRACK)
|
||||
#endif
|
||||
|
||||
#define alloc_thread_info_node(tsk, node) \
|
||||
((struct thread_info *)__get_free_pages(THREAD_FLAGS, THREAD_ORDER))
|
||||
|
||||
#define free_thread_info(ti) free_pages((unsigned long) (ti), THREAD_ORDER)
|
||||
#define get_thread_info(ti) get_task_struct((ti)->task)
|
||||
#define put_thread_info(ti) put_task_struct((ti)->task)
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#define PREEMPT_ACTIVE 0x10000000
|
||||
|
||||
/*
|
||||
* thread information flag bit numbers
|
||||
* - pending work-to-be-done flags are in LSW
|
||||
* - other flags in MSW
|
||||
*/
|
||||
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
|
||||
#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */
|
||||
#define TIF_SIGPENDING 2 /* signal pending */
|
||||
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
|
||||
#define TIF_RESTORE_SIGMASK 4 /* restore signal mask in do_signal() */
|
||||
|
||||
#define TIF_POLLING_NRFLAG 16 /* true if polling TIF_NEED_RESCHED */
|
||||
#define TIF_MEMDIE 17 /* OOM killer killed process */
|
||||
|
||||
#define TIF_WORK_MASK 0x00007FFE /* work on irq/exception return */
|
||||
#define TIF_ALLWORK_MASK 0x00007FFF /* work on any return to u-space */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _ASM_C6X_THREAD_INFO_H */
|
263
arch/c6x/kernel/process.c
Normal file
263
arch/c6x/kernel/process.c
Normal file
@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Port on Texas Instruments TMS320C6x architecture
|
||||
*
|
||||
* Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated
|
||||
* Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/init_task.h>
|
||||
#include <linux/tick.h>
|
||||
#include <linux/mqueue.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/reboot.h>
|
||||
|
||||
#include <asm/syscalls.h>
|
||||
|
||||
/* hooks for board specific support */
|
||||
void (*c6x_restart)(void);
|
||||
void (*c6x_halt)(void);
|
||||
|
||||
extern asmlinkage void ret_from_fork(void);
|
||||
|
||||
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
|
||||
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
|
||||
|
||||
/*
|
||||
* Initial thread structure.
|
||||
*/
|
||||
union thread_union init_thread_union __init_task_data = {
|
||||
INIT_THREAD_INFO(init_task)
|
||||
};
|
||||
|
||||
/*
|
||||
* Initial task structure.
|
||||
*/
|
||||
struct task_struct init_task = INIT_TASK(init_task);
|
||||
EXPORT_SYMBOL(init_task);
|
||||
|
||||
/*
|
||||
* power off function, if any
|
||||
*/
|
||||
void (*pm_power_off)(void);
|
||||
EXPORT_SYMBOL(pm_power_off);
|
||||
|
||||
static void c6x_idle(void)
|
||||
{
|
||||
unsigned long tmp;
|
||||
|
||||
/*
|
||||
* Put local_irq_enable and idle in same execute packet
|
||||
* to make them atomic and avoid race to idle with
|
||||
* interrupts enabled.
|
||||
*/
|
||||
asm volatile (" mvc .s2 CSR,%0\n"
|
||||
" or .d2 1,%0,%0\n"
|
||||
" mvc .s2 %0,CSR\n"
|
||||
"|| idle\n"
|
||||
: "=b"(tmp));
|
||||
}
|
||||
|
||||
/*
|
||||
* The idle loop for C64x
|
||||
*/
|
||||
void cpu_idle(void)
|
||||
{
|
||||
/* endless idle loop with no priority at all */
|
||||
while (1) {
|
||||
tick_nohz_stop_sched_tick(1);
|
||||
while (1) {
|
||||
local_irq_disable();
|
||||
if (need_resched()) {
|
||||
local_irq_enable();
|
||||
break;
|
||||
}
|
||||
c6x_idle(); /* enables local irqs */
|
||||
}
|
||||
tick_nohz_restart_sched_tick();
|
||||
|
||||
preempt_enable_no_resched();
|
||||
schedule();
|
||||
preempt_disable();
|
||||
}
|
||||
}
|
||||
|
||||
static void halt_loop(void)
|
||||
{
|
||||
printk(KERN_EMERG "System Halted, OK to turn off power\n");
|
||||
local_irq_disable();
|
||||
while (1)
|
||||
asm volatile("idle\n");
|
||||
}
|
||||
|
||||
void machine_restart(char *__unused)
|
||||
{
|
||||
if (c6x_restart)
|
||||
c6x_restart();
|
||||
halt_loop();
|
||||
}
|
||||
|
||||
void machine_halt(void)
|
||||
{
|
||||
if (c6x_halt)
|
||||
c6x_halt();
|
||||
halt_loop();
|
||||
}
|
||||
|
||||
void machine_power_off(void)
|
||||
{
|
||||
if (pm_power_off)
|
||||
pm_power_off();
|
||||
halt_loop();
|
||||
}
|
||||
|
||||
static void kernel_thread_helper(int dummy, void *arg, int (*fn)(void *))
|
||||
{
|
||||
do_exit(fn(arg));
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a kernel thread
|
||||
*/
|
||||
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
|
||||
{
|
||||
struct pt_regs regs;
|
||||
|
||||
/*
|
||||
* copy_thread sets a4 to zero (child return from fork)
|
||||
* so we can't just set things up to directly return to
|
||||
* fn.
|
||||
*/
|
||||
memset(®s, 0, sizeof(regs));
|
||||
regs.b4 = (unsigned long) arg;
|
||||
regs.a6 = (unsigned long) fn;
|
||||
regs.pc = (unsigned long) kernel_thread_helper;
|
||||
local_save_flags(regs.csr);
|
||||
regs.csr |= 1;
|
||||
regs.tsr = 5; /* Set GEE and GIE in TSR */
|
||||
|
||||
/* Ok, create the new process.. */
|
||||
return do_fork(flags | CLONE_VM | CLONE_UNTRACED, -1, ®s,
|
||||
0, NULL, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL(kernel_thread);
|
||||
|
||||
void flush_thread(void)
|
||||
{
|
||||
}
|
||||
|
||||
void exit_thread(void)
|
||||
{
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE1(c6x_clone, struct pt_regs *, regs)
|
||||
{
|
||||
unsigned long clone_flags;
|
||||
unsigned long newsp;
|
||||
|
||||
/* syscall puts clone_flags in A4 and usp in B4 */
|
||||
clone_flags = regs->orig_a4;
|
||||
if (regs->b4)
|
||||
newsp = regs->b4;
|
||||
else
|
||||
newsp = regs->sp;
|
||||
|
||||
return do_fork(clone_flags, newsp, regs, 0, (int __user *)regs->a6,
|
||||
(int __user *)regs->b6);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do necessary setup to start up a newly executed thread.
|
||||
*/
|
||||
void start_thread(struct pt_regs *regs, unsigned int pc, unsigned long usp)
|
||||
{
|
||||
/*
|
||||
* The binfmt loader will setup a "full" stack, but the C6X
|
||||
* operates an "empty" stack. So we adjust the usp so that
|
||||
* argc doesn't get destroyed if an interrupt is taken before
|
||||
* it is read from the stack.
|
||||
*
|
||||
* NB: Library startup code needs to match this.
|
||||
*/
|
||||
usp -= 8;
|
||||
|
||||
set_fs(USER_DS);
|
||||
regs->pc = pc;
|
||||
regs->sp = usp;
|
||||
regs->tsr |= 0x40; /* set user mode */
|
||||
current->thread.usp = usp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy a new thread context in its stack.
|
||||
*/
|
||||
int copy_thread(unsigned long clone_flags, unsigned long usp,
|
||||
unsigned long ustk_size,
|
||||
struct task_struct *p, struct pt_regs *regs)
|
||||
{
|
||||
struct pt_regs *childregs;
|
||||
|
||||
childregs = task_pt_regs(p);
|
||||
|
||||
*childregs = *regs;
|
||||
childregs->a4 = 0;
|
||||
|
||||
if (usp == -1)
|
||||
/* case of __kernel_thread: we return to supervisor space */
|
||||
childregs->sp = (unsigned long)(childregs + 1);
|
||||
else
|
||||
/* Otherwise use the given stack */
|
||||
childregs->sp = usp;
|
||||
|
||||
/* Set usp/ksp */
|
||||
p->thread.usp = childregs->sp;
|
||||
/* switch_to uses stack to save/restore 14 callee-saved regs */
|
||||
thread_saved_ksp(p) = (unsigned long)childregs - 8;
|
||||
p->thread.pc = (unsigned int) ret_from_fork;
|
||||
p->thread.wchan = (unsigned long) ret_from_fork;
|
||||
#ifdef __DSBT__
|
||||
{
|
||||
unsigned long dp;
|
||||
|
||||
asm volatile ("mv .S2 b14,%0\n" : "=b"(dp));
|
||||
|
||||
thread_saved_dp(p) = dp;
|
||||
if (usp == -1)
|
||||
childregs->dp = dp;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* c6x_execve() executes a new program.
|
||||
*/
|
||||
SYSCALL_DEFINE4(c6x_execve, const char __user *, name,
|
||||
const char __user *const __user *, argv,
|
||||
const char __user *const __user *, envp,
|
||||
struct pt_regs *, regs)
|
||||
{
|
||||
int error;
|
||||
char *filename;
|
||||
|
||||
filename = getname(name);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
|
||||
error = do_execve(filename, argv, envp, regs);
|
||||
putname(filename);
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
|
||||
unsigned long get_wchan(struct task_struct *p)
|
||||
{
|
||||
return p->thread.wchan;
|
||||
}
|
74
arch/c6x/kernel/switch_to.S
Normal file
74
arch/c6x/kernel/switch_to.S
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Texas Instruments Incorporated
|
||||
* Author: Mark Salter (msalter@redhat.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
|
||||
#define SP B15
|
||||
|
||||
/*
|
||||
* void __switch_to(struct thread_info *prev,
|
||||
* struct thread_info *next,
|
||||
* struct task_struct *tsk) ;
|
||||
*/
|
||||
ENTRY(__switch_to)
|
||||
LDDW .D2T2 *+B4(THREAD_B15_14),B7:B6
|
||||
|| MV .L2X A4,B5 ; prev
|
||||
|| MV .L1X B4,A5 ; next
|
||||
|| MVC .S2 RILC,B1
|
||||
|
||||
STW .D2T2 B3,*+B5(THREAD_PC)
|
||||
|| STDW .D1T1 A13:A12,*+A4(THREAD_A13_12)
|
||||
|| MVC .S2 ILC,B0
|
||||
|
||||
LDW .D2T2 *+B4(THREAD_PC),B3
|
||||
|| LDDW .D1T1 *+A5(THREAD_A13_12),A13:A12
|
||||
|
||||
STDW .D1T1 A11:A10,*+A4(THREAD_A11_10)
|
||||
|| STDW .D2T2 B1:B0,*+B5(THREAD_RICL_ICL)
|
||||
#ifndef __DSBT__
|
||||
|| MVKL .S2 current_ksp,B1
|
||||
#endif
|
||||
|
||||
STDW .D2T2 B15:B14,*+B5(THREAD_B15_14)
|
||||
|| STDW .D1T1 A15:A14,*+A4(THREAD_A15_14)
|
||||
#ifndef __DSBT__
|
||||
|| MVKH .S2 current_ksp,B1
|
||||
#endif
|
||||
|
||||
;; Switch to next SP
|
||||
MV .S2 B7,SP
|
||||
#ifdef __DSBT__
|
||||
|| STW .D2T2 B7,*+B14(current_ksp)
|
||||
#else
|
||||
|| STW .D2T2 B7,*B1
|
||||
|| MV .L2 B6,B14
|
||||
#endif
|
||||
|| LDDW .D1T1 *+A5(THREAD_RICL_ICL),A1:A0
|
||||
|
||||
STDW .D2T2 B11:B10,*+B5(THREAD_B11_10)
|
||||
|| LDDW .D1T1 *+A5(THREAD_A15_14),A15:A14
|
||||
|
||||
STDW .D2T2 B13:B12,*+B5(THREAD_B13_12)
|
||||
|| LDDW .D1T1 *+A5(THREAD_A11_10),A11:A10
|
||||
|
||||
B .S2 B3 ; return in next E1
|
||||
|| LDDW .D2T2 *+B4(THREAD_B13_12),B13:B12
|
||||
|
||||
LDDW .D2T2 *+B4(THREAD_B11_10),B11:B10
|
||||
NOP
|
||||
|
||||
MV .L2X A0,B0
|
||||
|| MV .S1 A6,A4
|
||||
|
||||
MVC .S2 B0,ILC
|
||||
|| MV .L2X A1,B1
|
||||
|
||||
MVC .S2 B1,RILC
|
||||
ENDPROC(__switch_to)
|
Loading…
Reference in New Issue
Block a user