Преглед на файлове

efDataPreprocessing memoryCall.c 沈瑞清 commit at 2021-04-21

沈瑞清 преди 4 години
родител
ревизия
6cf9046848
променени са 1 файла, в които са добавени 156 реда и са изтрити 0 реда
  1. 156 0
      efDataPreprocessing/dataSharedMemory/memoryCall.c

+ 156 - 0
efDataPreprocessing/dataSharedMemory/memoryCall.c

@@ -929,3 +929,159 @@ do_entUnaUser(void __user * va, unsigned long opcode,
 		__asm__ __volatile__(
 		"1:	ldq_u %2,1(%5)\n"
 		"2:	ldq_u %1,0(%5)\n"
+		"	inswh %6,%5,%4\n"
+		"	inswl %6,%5,%3\n"
+		"	mskwh %2,%5,%2\n"
+		"	mskwl %1,%5,%1\n"
+		"	or %2,%4,%2\n"
+		"	or %1,%3,%1\n"
+		"3:	stq_u %2,1(%5)\n"
+		"4:	stq_u %1,0(%5)\n"
+		"5:\n"
+		".section __ex_table,\"a\"\n"
+		"	.long 1b - .\n"
+		"	lda %2,5b-1b(%0)\n"
+		"	.long 2b - .\n"
+		"	lda %1,5b-2b(%0)\n"
+		"	.long 3b - .\n"
+		"	lda $31,5b-3b(%0)\n"
+		"	.long 4b - .\n"
+		"	lda $31,5b-4b(%0)\n"
+		".previous"
+			: "=r"(error), "=&r"(tmp1), "=&r"(tmp2),
+			  "=&r"(tmp3), "=&r"(tmp4)
+			: "r"(va), "r"(*reg_addr), "0"(0));
+		if (error)
+			goto give_sigsegv;
+		return;
+
+	case 0x26: /* sts */
+		fake_reg = s_reg_to_mem(alpha_read_fp_reg(reg));
+		/* FALLTHRU */
+
+	case 0x2c: /* stl */
+		__asm__ __volatile__(
+		"1:	ldq_u %2,3(%5)\n"
+		"2:	ldq_u %1,0(%5)\n"
+		"	inslh %6,%5,%4\n"
+		"	insll %6,%5,%3\n"
+		"	msklh %2,%5,%2\n"
+		"	mskll %1,%5,%1\n"
+		"	or %2,%4,%2\n"
+		"	or %1,%3,%1\n"
+		"3:	stq_u %2,3(%5)\n"
+		"4:	stq_u %1,0(%5)\n"
+		"5:\n"
+		".section __ex_table,\"a\"\n"
+		"	.long 1b - .\n"
+		"	lda %2,5b-1b(%0)\n"
+		"	.long 2b - .\n"
+		"	lda %1,5b-2b(%0)\n"
+		"	.long 3b - .\n"
+		"	lda $31,5b-3b(%0)\n"
+		"	.long 4b - .\n"
+		"	lda $31,5b-4b(%0)\n"
+		".previous"
+			: "=r"(error), "=&r"(tmp1), "=&r"(tmp2),
+			  "=&r"(tmp3), "=&r"(tmp4)
+			: "r"(va), "r"(*reg_addr), "0"(0));
+		if (error)
+			goto give_sigsegv;
+		return;
+
+	case 0x27: /* stt */
+		fake_reg = alpha_read_fp_reg(reg);
+		/* FALLTHRU */
+
+	case 0x2d: /* stq */
+		__asm__ __volatile__(
+		"1:	ldq_u %2,7(%5)\n"
+		"2:	ldq_u %1,0(%5)\n"
+		"	insqh %6,%5,%4\n"
+		"	insql %6,%5,%3\n"
+		"	mskqh %2,%5,%2\n"
+		"	mskql %1,%5,%1\n"
+		"	or %2,%4,%2\n"
+		"	or %1,%3,%1\n"
+		"3:	stq_u %2,7(%5)\n"
+		"4:	stq_u %1,0(%5)\n"
+		"5:\n"
+		".section __ex_table,\"a\"\n\t"
+		"	.long 1b - .\n"
+		"	lda %2,5b-1b(%0)\n"
+		"	.long 2b - .\n"
+		"	lda %1,5b-2b(%0)\n"
+		"	.long 3b - .\n"
+		"	lda $31,5b-3b(%0)\n"
+		"	.long 4b - .\n"
+		"	lda $31,5b-4b(%0)\n"
+		".previous"
+			: "=r"(error), "=&r"(tmp1), "=&r"(tmp2),
+			  "=&r"(tmp3), "=&r"(tmp4)
+			: "r"(va), "r"(*reg_addr), "0"(0));
+		if (error)
+			goto give_sigsegv;
+		return;
+
+	default:
+		/* What instruction were you trying to use, exactly?  */
+		goto give_sigbus;
+	}
+
+	/* Only integer loads should get here; everyone else returns early. */
+	if (reg == 30)
+		wrusp(fake_reg);
+	return;
+
+give_sigsegv:
+	regs->pc -= 4;  /* make pc point to faulting insn */
+	info.si_signo = SIGSEGV;
+	info.si_errno = 0;
+
+	/* We need to replicate some of the logic in mm/fault.c,
+	   since we don't have access to the fault code in the
+	   exception handling return path.  */
+	if (!__access_ok((unsigned long)va, 0, USER_DS))
+		info.si_code = SEGV_ACCERR;
+	else {
+		struct mm_struct *mm = current->mm;
+		down_read(&mm->mmap_sem);
+		if (find_vma(mm, (unsigned long)va))
+			info.si_code = SEGV_ACCERR;
+		else
+			info.si_code = SEGV_MAPERR;
+		up_read(&mm->mmap_sem);
+	}
+	info.si_addr = va;
+	send_sig_info(SIGSEGV, &info, current);
+	return;
+
+give_sigbus:
+	regs->pc -= 4;
+	info.si_signo = SIGBUS;
+	info.si_errno = 0;
+	info.si_code = BUS_ADRALN;
+	info.si_addr = va;
+	send_sig_info(SIGBUS, &info, current);
+	return;
+}
+
+void __cpuinit
+trap_init(void)
+{
+	/* Tell PAL-code what global pointer we want in the kernel.  */
+	register unsigned long gptr __asm__("$29");
+	wrkgp(gptr);
+
+	/* Hack for Multia (UDB) and JENSEN: some of their SRMs have
+	   a bug in the handling of the opDEC fault.  Fix it up if so.  */
+	if (implver() == IMPLVER_EV4)
+		opDEC_check();
+
+	wrent(entArith, 1);
+	wrent(entMM, 2);
+	wrent(entIF, 3);
+	wrent(entUna, 4);
+	wrent(entSys, 5);
+	wrent(entDbg, 6);
+}