git: e967ace28f4b - stable/13 - Implement suword16() for the 32/64-bit PowerPC architecture.

From: Hans Petter Selasky <hselasky_at_FreeBSD.org>
Date: Fri, 07 Jan 2022 13:30:57 UTC
The branch stable/13 has been updated by hselasky:

URL: https://cgit.FreeBSD.org/src/commit/?id=e967ace28f4b38e0667c53769d984220590c8fd4

commit e967ace28f4b38e0667c53769d984220590c8fd4
Author:     Hans Petter Selasky <hselasky@FreeBSD.org>
AuthorDate: 2021-12-19 11:19:53 +0000
Commit:     Hans Petter Selasky <hselasky@FreeBSD.org>
CommitDate: 2022-01-07 13:25:17 +0000

    Implement suword16() for the 32/64-bit PowerPC architecture.
    
    Sponsored by:   NVIDIA Networking
    
    (cherry picked from commit e98efdd973560e66557f3ab46ca10376acb3c583)
    (cherry picked from commit eb771bf6f496538d2f621780702200f5390ff435)
---
 sys/powerpc/powerpc/copyinout.c | 31 +++++++++++++++++++++++++++++++
 sys/powerpc/powerpc/support.S   |  8 ++++++++
 2 files changed, 39 insertions(+)

diff --git a/sys/powerpc/powerpc/copyinout.c b/sys/powerpc/powerpc/copyinout.c
index 1528accc0e0e..f6720e8ba09e 100644
--- a/sys/powerpc/powerpc/copyinout.c
+++ b/sys/powerpc/powerpc/copyinout.c
@@ -99,6 +99,8 @@ int copyout_remap(const void *kaddr, void *udaddr, size_t len);
 int copyout_direct(const void *kaddr, void *udaddr, size_t len);
 int copyin_remap(const void *uaddr, void *kaddr, size_t len);
 int copyin_direct(const void *uaddr, void *kaddr, size_t len);
+int suword16_remap(volatile void *addr, int word);
+int suword16_direct(volatile void *addr, int word);
 int suword32_remap(volatile void *addr, int word);
 int suword32_direct(volatile void *addr, int word);
 int suword_remap(volatile void *addr, long word);
@@ -139,6 +141,7 @@ DEFINE_COPY_FUNC(int, copyinstr, (const void *, void *, size_t, size_t *))
 DEFINE_COPY_FUNC(int, copyin, (const void *, void *, size_t))
 DEFINE_COPY_FUNC(int, copyout, (const void *, void *, size_t))
 DEFINE_COPY_FUNC(int, suword, (volatile void *, long))
+DEFINE_COPY_FUNC(int, suword16, (volatile void *, int))
 DEFINE_COPY_FUNC(int, suword32, (volatile void *, int))
 DEFINE_COPY_FUNC(int, suword64, (volatile void *, int64_t))
 DEFINE_COPY_FUNC(int, fubyte, (volatile const void *))
@@ -314,6 +317,34 @@ REMAP(subyte)(volatile void *addr, int byte)
 	return (0);
 }
 
+int
+REMAP(suword16)(volatile void *addr, int word)
+{
+	struct		thread *td;
+	pmap_t		pm;
+	jmp_buf		env;
+	int16_t		*p;
+
+	td = curthread;
+	pm = &td->td_proc->p_vmspace->vm_pmap;
+
+	td->td_pcb->pcb_onfault = &env;
+	if (setjmp(env)) {
+		td->td_pcb->pcb_onfault = NULL;
+		return (-1);
+	}
+
+	if (pmap_map_user_ptr(pm, addr, (void **)&p, sizeof(*p), NULL)) {
+		td->td_pcb->pcb_onfault = NULL;
+		return (-1);
+	}
+
+	*p = (int16_t)word;
+
+	td->td_pcb->pcb_onfault = NULL;
+	return (0);
+}
+
 #ifdef __powerpc64__
 int
 REMAP(suword32)(volatile void *addr, int word)
diff --git a/sys/powerpc/powerpc/support.S b/sys/powerpc/powerpc/support.S
index 10d3192972d5..89dccd558014 100644
--- a/sys/powerpc/powerpc/support.S
+++ b/sys/powerpc/powerpc/support.S
@@ -401,6 +401,14 @@ ENTRY_DIRECT(suword)
 END_DIRECT(suword)
 #endif	
 
+ENTRY_DIRECT(suword16)
+	PROLOGUE
+	SET_FUSUFAULT(%r3, %r7)
+	sth  %r4, 0(%r3)
+	CLEAR_FAULT(%r7)
+	EPILOGUE
+END_DIRECT(suword16)
+
 ENTRY_DIRECT(suword32)
 	PROLOGUE
 	SET_FUSUFAULT(%r3, %r7)