summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVisa Hankala <visa@cvs.openbsd.org>2017-05-21 13:00:54 +0000
committerVisa Hankala <visa@cvs.openbsd.org>2017-05-21 13:00:54 +0000
commit799df8f1ea252a453c6519ce1108d5bb52ca6109 (patch)
tree09db6f2494a20adffaa9a5acbdd05425f5ef3761
parented3a9a1e17cf4ba2d1a8476904c0e1e989ac1aa1 (diff)
Enable radeondrm(4) on loongson to get accelerated graphics
with the RS780E chipset. OK kettenis@, jsg@
-rw-r--r--etc/etc.loongson/MAKEDEV.md4
-rw-r--r--sys/arch/loongson/conf/GENERIC5
-rw-r--r--sys/arch/loongson/include/autoconf.h3
-rw-r--r--sys/arch/loongson/include/pmon.h3
-rw-r--r--sys/arch/loongson/include/vmparam.h4
-rw-r--r--sys/arch/loongson/loongson/conf.c16
-rw-r--r--sys/arch/loongson/loongson/generic3a_machdep.c7
-rw-r--r--sys/arch/loongson/loongson/machdep.c3
-rw-r--r--sys/arch/loongson/loongson/pmon.c12
-rw-r--r--sys/arch/mips64/conf/files.mips643
-rw-r--r--sys/dev/pci/drm/radeon/radeon_bios.c14
-rw-r--r--sys/kern/kern_pledge.c5
-rw-r--r--sys/lib/libkern/arch/mips64/sync.S317
-rw-r--r--sys/uvm/uvm_device.c5
14 files changed, 384 insertions, 17 deletions
diff --git a/etc/etc.loongson/MAKEDEV.md b/etc/etc.loongson/MAKEDEV.md
index b1457ca3392..1dabb4d8260 100644
--- a/etc/etc.loongson/MAKEDEV.md
+++ b/etc/etc.loongson/MAKEDEV.md
@@ -1,6 +1,6 @@
define(MACHINE,loongson)dnl
vers(__file__,
- {-$OpenBSD: MAKEDEV.md,v 1.26 2016/09/04 15:38:59 naddy Exp $-},
+ {-$OpenBSD: MAKEDEV.md,v 1.27 2017/05/21 13:00:53 visa Exp $-},
etc.MACHINE)dnl
dnl
dnl Copyright (c) 2001-2006 Todd T. Fries <todd@OpenBSD.org>
@@ -67,6 +67,7 @@ _DEV(au, 44)
_DEV(bio, 49)
_DEV(bpf, 12)
_DEV(diskmap, 70)
+_DEV(drm, 87)
_DEV(fdesc, 7)
_DEV(fuse, 73)
_DEV(hotplug, 67)
@@ -104,6 +105,7 @@ target(all, cd, 0, 1)dnl
target(all, sd, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)dnl
target(all, vnd, 0, 1, 2, 3)dnl
target(all, switch, 0, 1, 2, 3)dnl
+target(all, drm, 0, 1, 2, 3)dnl
target(ramd, pty, 0)dnl
target(ramd, bio)dnl
target(ramd, diskmap)dnl
diff --git a/sys/arch/loongson/conf/GENERIC b/sys/arch/loongson/conf/GENERIC
index 0fa6a2d10b4..0d24a1d5d69 100644
--- a/sys/arch/loongson/conf/GENERIC
+++ b/sys/arch/loongson/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.54 2016/11/17 14:44:34 visa Exp $
+# $OpenBSD: GENERIC,v 1.55 2017/05/21 13:00:53 visa Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
@@ -86,6 +86,9 @@ audio* at azalia?
piixpm* at pci?
iic* at piixpm?
spdmem* at iic?
+radeondrm* at pci?
+drm* at radeondrm?
+wsdisplay* at radeondrm?
radeonfb* at pci?
wsdisplay* at radeonfb?
diff --git a/sys/arch/loongson/include/autoconf.h b/sys/arch/loongson/include/autoconf.h
index 6c87ee8f841..1a31fcf5a58 100644
--- a/sys/arch/loongson/include/autoconf.h
+++ b/sys/arch/loongson/include/autoconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: autoconf.h,v 1.16 2017/05/10 15:21:02 visa Exp $ */
+/* $OpenBSD: autoconf.h,v 1.17 2017/05/21 13:00:53 visa Exp $ */
/*
* Copyright (c) 2001-2003 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -92,6 +92,7 @@ struct platform {
#define LOONGSON_MAXCPUS 16
extern const struct platform *sys_platform;
+extern void *loongson_videobios;
extern uint loongson_cpumask;
extern uint loongson_ver;
extern int nnodes;
diff --git a/sys/arch/loongson/include/pmon.h b/sys/arch/loongson/include/pmon.h
index 1efcf2495ff..4616052054d 100644
--- a/sys/arch/loongson/include/pmon.h
+++ b/sys/arch/loongson/include/pmon.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmon.h,v 1.4 2016/11/22 15:44:24 visa Exp $ */
+/* $OpenBSD: pmon.h,v 1.5 2017/05/21 13:00:53 visa Exp $ */
/*
* Copyright (c) 2009, 2012 Miodrag Vallat.
@@ -195,6 +195,7 @@ struct pmon_env_device {
const char *pmon_getenv(const char *);
const struct pmon_env_reset *pmon_get_env_reset(void);
+const struct pmon_env_smbios *pmon_get_env_smbios(void);
const struct pmon_env_mem *pmon_get_env_mem(void);
const struct pmon_env_cpu *pmon_get_env_cpu(void);
const struct pmon_env_sys *pmon_get_env_sys(void);
diff --git a/sys/arch/loongson/include/vmparam.h b/sys/arch/loongson/include/vmparam.h
index be5d726ec4e..597a26179a5 100644
--- a/sys/arch/loongson/include/vmparam.h
+++ b/sys/arch/loongson/include/vmparam.h
@@ -1,9 +1,9 @@
-/* $OpenBSD: vmparam.h,v 1.4 2014/03/27 21:58:13 miod Exp $ */
+/* $OpenBSD: vmparam.h,v 1.5 2017/05/21 13:00:53 visa Exp $ */
/* public domain */
#ifndef _MACHINE_VMPARAM_H_
#define _MACHINE_VMPARAM_H_
-#define VM_PHYSSEG_MAX 3 /* Max number of physical memory segments */
+#define VM_PHYSSEG_MAX 8 /* Max number of physical memory segments */
#define VM_PHYSSEG_STRAT VM_PSTRAT_BIGFIRST
#include <mips64/vmparam.h>
diff --git a/sys/arch/loongson/loongson/conf.c b/sys/arch/loongson/loongson/conf.c
index 3aa932a0485..87746db5225 100644
--- a/sys/arch/loongson/loongson/conf.c
+++ b/sys/arch/loongson/loongson/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.23 2016/09/04 10:51:23 naddy Exp $ */
+/* $OpenBSD: conf.c,v 1.24 2017/05/21 13:00:53 visa Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -98,6 +98,8 @@ cdev_decl(fd);
#include "apm.h"
#include "com.h"
cdev_decl(com);
+#include "drm.h"
+cdev_decl(drm);
#include "lpt.h"
cdev_decl(lpt);
#include "ch.h"
@@ -209,6 +211,18 @@ struct cdevsw cdevsw[] =
cdev_fuse_init(NFUSE,fuse), /* 73: fuse */
cdev_tun_init(NTUN,tap), /* 74: Ethernet network tunnel */
cdev_switch_init(NSWITCH,switch), /* 75: switch(4) control interface */
+ cdev_notdef(), /* 76 */
+ cdev_notdef(), /* 77 */
+ cdev_notdef(), /* 78 */
+ cdev_notdef(), /* 79 */
+ cdev_notdef(), /* 80 */
+ cdev_notdef(), /* 81 */
+ cdev_notdef(), /* 82 */
+ cdev_notdef(), /* 83 */
+ cdev_notdef(), /* 84 */
+ cdev_notdef(), /* 85 */
+ cdev_notdef(), /* 86 */
+ cdev_drm_init(NDRM,drm), /* 87: drm */
};
int nchrdev = nitems(cdevsw);
diff --git a/sys/arch/loongson/loongson/generic3a_machdep.c b/sys/arch/loongson/loongson/generic3a_machdep.c
index 7c26088783e..ac3f1db6ccd 100644
--- a/sys/arch/loongson/loongson/generic3a_machdep.c
+++ b/sys/arch/loongson/loongson/generic3a_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: generic3a_machdep.c,v 1.7 2017/05/10 16:04:21 visa Exp $ */
+/* $OpenBSD: generic3a_machdep.c,v 1.8 2017/05/21 13:00:53 visa Exp $ */
/*
* Copyright (c) 2009, 2010, 2012 Miodrag Vallat.
@@ -187,6 +187,7 @@ void
generic3a_setup(void)
{
const struct pmon_env_reset *resetenv = pmon_get_env_reset();
+ const struct pmon_env_smbios *smbios = pmon_get_env_smbios();
uint32_t boot_cpuid = loongson3_get_cpuid();
/* Override the mask if it misses the boot CPU. */
@@ -202,6 +203,10 @@ generic3a_setup(void)
generic3a_poweroff_entry = resetenv->poweroff;
}
+ if (smbios != NULL)
+ /* pmon_init() has checked that `vga_bios' points to kseg0. */
+ loongson_videobios = (void *)smbios->vga_bios;
+
loongson3_intr_init();
#ifdef MULTIPROCESSOR
diff --git a/sys/arch/loongson/loongson/machdep.c b/sys/arch/loongson/loongson/machdep.c
index 3100d7cf40c..d5f8984fe3d 100644
--- a/sys/arch/loongson/loongson/machdep.c
+++ b/sys/arch/loongson/loongson/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.77 2017/04/30 16:45:45 mpi Exp $ */
+/* $OpenBSD: machdep.c,v 1.78 2017/05/21 13:00:53 visa Exp $ */
/*
* Copyright (c) 2009, 2010, 2014 Miodrag Vallat.
@@ -126,6 +126,7 @@ uint32_t ipi_mask;
const struct platform *sys_platform;
struct cpu_hwinfo bootcpu_hwinfo;
+void *loongson_videobios;
uint loongson_cpumask = 1;
uint loongson_ver;
diff --git a/sys/arch/loongson/loongson/pmon.c b/sys/arch/loongson/loongson/pmon.c
index 98202ca3890..44ca8e8a5cf 100644
--- a/sys/arch/loongson/loongson/pmon.c
+++ b/sys/arch/loongson/loongson/pmon.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pmon.c,v 1.6 2016/09/28 14:46:34 visa Exp $ */
+/* $OpenBSD: pmon.c,v 1.7 2017/05/21 13:00:53 visa Exp $ */
/*
* Copyright (c) 2009, 2012 Miodrag Vallat.
@@ -184,6 +184,16 @@ const struct pmon_env_reset *pmon_get_env_reset()
return &env->reset;
}
+const struct pmon_env_smbios *pmon_get_env_smbios()
+{
+ struct pmon_env *env = (struct pmon_env *)pmon_envp;
+
+ if (pmon_envtype != PMON_ENVTYPE_EFI)
+ return NULL;
+
+ return &env->efi.bios;
+}
+
const struct pmon_env_mem *pmon_get_env_mem()
{
struct pmon_env *env = (struct pmon_env *)pmon_envp;
diff --git a/sys/arch/mips64/conf/files.mips64 b/sys/arch/mips64/conf/files.mips64
index a33de306281..b3f7153e6f9 100644
--- a/sys/arch/mips64/conf/files.mips64
+++ b/sys/arch/mips64/conf/files.mips64
@@ -1,4 +1,4 @@
-# $OpenBSD: files.mips64,v 1.26 2015/09/09 15:48:52 visa Exp $
+# $OpenBSD: files.mips64,v 1.27 2017/05/21 13:00:53 visa Exp $
file arch/mips64/mips64/arcbios.c arcbios
file arch/mips64/mips64/clock.c clock
@@ -47,3 +47,4 @@ file netinet/in_cksum.c
file netinet/in4_cksum.c
file lib/libkern/softfloat.c
+file lib/libkern/arch/mips64/sync.S drm
diff --git a/sys/dev/pci/drm/radeon/radeon_bios.c b/sys/dev/pci/drm/radeon/radeon_bios.c
index a935ceaf5af..e2c347312e5 100644
--- a/sys/dev/pci/drm/radeon/radeon_bios.c
+++ b/sys/dev/pci/drm/radeon/radeon_bios.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: radeon_bios.c,v 1.9 2016/02/06 11:59:51 kettenis Exp $ */
+/* $OpenBSD: radeon_bios.c,v 1.10 2017/05/21 13:00:53 visa Exp $ */
/*
* Copyright 2008 Advanced Micro Devices, Inc.
* Copyright 2008 Red Hat Inc.
@@ -37,6 +37,10 @@
#include <dev/isa/isavar.h>
#endif
+#if defined (__loongson__)
+#include <machine/autoconf.h>
+#endif
+
/*
* BIOS.
*/
@@ -46,7 +50,7 @@ bool radeon_read_platform_bios(struct radeon_device *);
bool
radeon_read_platform_bios(struct radeon_device *rdev)
{
-#if defined(__amd64__) || defined(__i386__)
+#if defined(__amd64__) || defined(__i386__) || defined(__loongson__)
uint8_t __iomem *bios;
bus_size_t size = 256 * 1024; /* ??? */
uint8_t *found = NULL;
@@ -59,7 +63,13 @@ radeon_read_platform_bios(struct radeon_device *rdev)
rdev->bios = NULL;
+#if defined(__loongson__)
+ if (loongson_videobios == NULL)
+ return false;
+ bios = loongson_videobios;
+#else
bios = (u8 *)ISA_HOLE_VADDR(0xc0000);
+#endif
for (i = 0; i + 2 < size; i++) {
if (bios[i] == 0x55 && bios[i + 1] == 0xaa) {
diff --git a/sys/kern/kern_pledge.c b/sys/kern/kern_pledge.c
index 20b1e70401d..ef4c766b263 100644
--- a/sys/kern/kern_pledge.c
+++ b/sys/kern/kern_pledge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_pledge.c,v 1.208 2017/05/02 16:46:00 natano Exp $ */
+/* $OpenBSD: kern_pledge.c,v 1.209 2017/05/21 13:00:53 visa Exp $ */
/*
* Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org>
@@ -77,7 +77,8 @@
#endif
#if defined(__amd64__) || defined(__i386__) || \
- defined(__macppc__) || defined(__sparc64__)
+ defined(__loongson__) || defined(__macppc__) || \
+ defined(__sparc64__)
#include "drm.h"
#endif
diff --git a/sys/lib/libkern/arch/mips64/sync.S b/sys/lib/libkern/arch/mips64/sync.S
new file mode 100644
index 00000000000..64f9b5c6dba
--- /dev/null
+++ b/sys/lib/libkern/arch/mips64/sync.S
@@ -0,0 +1,317 @@
+/* $OpenBSD: sync.S,v 1.1 2017/05/21 13:00:53 visa Exp $ */
+
+/*
+ * Copyright (c) 2015 Visa Hankala
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * The hardware can do 4-byte and 8-byte atomic operations directly through
+ * the ll/sc and lld/scd instructions. 1-byte and 2-byte atomic operations have
+ * to be emulated. The emulation uses 4-byte atomic updates where the change is
+ * confined to the desired 1-byte or 2-byte subword.
+ */
+
+ .set noreorder
+
+#define LEAF(n) \
+ .align 3; \
+ .globl n; \
+ .ent n, 0; \
+n:
+
+#define END(n) \
+ .end n
+
+/* Convert offset in memory to offset in machine word. */
+#ifdef __MIPSEB__
+#define GET_WORD_OFFSET(amask, r) xori r, r, amask
+#else
+#define GET_WORD_OFFSET(amask, r) /* nothing */
+#endif
+
+#define SYNC_EMUL_INIT(amask, vmask) \
+ andi $t0, $a0, amask; /* Get byte offset. */ \
+ xor $a0, $a0, $t0; /* Align the address. */ \
+ GET_WORD_OFFSET(amask, $t0); \
+ sll $t0, $t0, 3; /* Multiply by 8 to get bit shift. */ \
+ li $t1, vmask; \
+ sll $t1, $t1, $t0; /* Make positive mask. */ \
+ nor $t2, $t1, $0 /* Make negative mask. */
+
+#define NO_NEG
+#define NEG_v0 nor $v0, $v0, $0
+#define NEG_v1 nor $v1, $v1, $0
+
+#define NO_TRUNC
+#define TRUNC_32(r, t) \
+ lui t, 0xffff; \
+ ori t, t, 0xffff; \
+ and r, r, t
+
+/*
+ * type __sync_fetch_and_<op>_<N>(type *ptr, type value)
+ */
+
+#define SYNC_FETCH_AND_OP(op, n, ll, sc, inst, neg) \
+LEAF(__sync_fetch_and_##op##_##n); \
+1: ##ll $v0, ($a0); \
+ ##inst $v1, $v0, $a1; \
+ ##neg; \
+ ##sc $v1, ($a0); \
+ beq $v1, $0, 1b; \
+ nop; \
+ j $ra; \
+ nop; \
+END(__sync_fetch_and_##op##_##n)
+
+SYNC_FETCH_AND_OP(add, 8, lld, scd, daddu, NO_NEG)
+SYNC_FETCH_AND_OP(sub, 8, lld, scd, dsubu, NO_NEG)
+SYNC_FETCH_AND_OP(or, 8, lld, scd, or, NO_NEG)
+SYNC_FETCH_AND_OP(and, 8, lld, scd, and, NO_NEG)
+SYNC_FETCH_AND_OP(xor, 8, lld, scd, xor, NO_NEG)
+SYNC_FETCH_AND_OP(nand, 8, lld, scd, and, NEG_v1)
+
+SYNC_FETCH_AND_OP(add, 4, ll, sc, addu, NO_NEG)
+SYNC_FETCH_AND_OP(sub, 4, ll, sc, subu, NO_NEG)
+SYNC_FETCH_AND_OP(or, 4, ll, sc, or, NO_NEG)
+SYNC_FETCH_AND_OP(and, 4, ll, sc, and, NO_NEG)
+SYNC_FETCH_AND_OP(xor, 4, ll, sc, xor, NO_NEG)
+SYNC_FETCH_AND_OP(nand, 4, ll, sc, and, NEG_v1)
+
+#define SYNC_FETCH_AND_OP_EMUL(op, n, inst, neg, amask, vmask) \
+LEAF(__sync_fetch_and_##op##_##n); \
+ SYNC_EMUL_INIT(amask, vmask); \
+ sll $a1, $a1, $t0; /* Align the parameter. */ \
+ and $a1, $a1, $t1; /* Normalize the parameter. */ \
+1: ll $v0, ($a0); \
+ ##inst $v1, $v0, $a1; \
+ ##neg; \
+ and $v1, $v1, $t1; /* Get the new bits. */ \
+ and $t3, $v0, $t2; /* Get the old bits. */ \
+ or $v1, $v1, $t3; /* Combine the result. */ \
+ sc $v1, ($a0); \
+ beq $v1, $0, 1b; \
+ nop; \
+ and $v0, $v0, $t1; /* Get the old value. */ \
+ j $ra; \
+ srl $v0, $v0, $t0; /* Remove the shift. */ \
+END(__sync_fetch_and_##op##_##n)
+
+SYNC_FETCH_AND_OP_EMUL(add, 2, addu, NO_NEG, 2, 0xffff)
+SYNC_FETCH_AND_OP_EMUL(sub, 2, subu, NO_NEG, 2, 0xffff)
+SYNC_FETCH_AND_OP_EMUL(or, 2, or, NO_NEG, 2, 0xffff)
+SYNC_FETCH_AND_OP_EMUL(and, 2, and, NO_NEG, 2, 0xffff)
+SYNC_FETCH_AND_OP_EMUL(xor, 2, xor, NO_NEG, 2, 0xffff)
+SYNC_FETCH_AND_OP_EMUL(nand, 2, and, NEG_v1, 2, 0xffff)
+
+SYNC_FETCH_AND_OP_EMUL(add, 1, addu, NO_NEG, 3, 0xff)
+SYNC_FETCH_AND_OP_EMUL(sub, 1, subu, NO_NEG, 3, 0xff)
+SYNC_FETCH_AND_OP_EMUL(or, 1, or, NO_NEG, 3, 0xff)
+SYNC_FETCH_AND_OP_EMUL(and, 1, and, NO_NEG, 3, 0xff)
+SYNC_FETCH_AND_OP_EMUL(xor, 1, xor, NO_NEG, 3, 0xff)
+SYNC_FETCH_AND_OP_EMUL(nand, 1, and, NEG_v1, 3, 0xff)
+
+/*
+ * type __sync_<op>_and_fetch_<N>(type *ptr, type value)
+ */
+
+#define SYNC_OP_AND_FETCH(op, n, ll, sc, inst, neg) \
+LEAF(__sync_##op##_and_fetch_##n); \
+1: ##ll $v0, ($a0); \
+ ##inst $v0, $v0, $a1; \
+ ##neg; \
+ move $v1, $v0; \
+ ##sc $v1, ($a0); \
+ beq $v1, $0, 1b; \
+ nop; \
+ j $ra; \
+ nop; \
+END(__sync_##op##_and_fetch_##n)
+
+SYNC_OP_AND_FETCH(add, 8, lld, scd, daddu, NO_NEG)
+SYNC_OP_AND_FETCH(sub, 8, lld, scd, dsubu, NO_NEG)
+SYNC_OP_AND_FETCH(or, 8, lld, scd, or, NO_NEG)
+SYNC_OP_AND_FETCH(and, 8, lld, scd, and, NO_NEG)
+SYNC_OP_AND_FETCH(xor, 8, lld, scd, xor, NO_NEG)
+SYNC_OP_AND_FETCH(nand, 8, lld, scd, and, NEG_v0)
+
+SYNC_OP_AND_FETCH(add, 4, ll, sc, addu, NO_NEG)
+SYNC_OP_AND_FETCH(sub, 4, ll, sc, subu, NO_NEG)
+SYNC_OP_AND_FETCH(or, 4, ll, sc, or, NO_NEG)
+SYNC_OP_AND_FETCH(and, 4, ll, sc, and, NO_NEG)
+SYNC_OP_AND_FETCH(xor, 4, ll, sc, xor, NO_NEG)
+SYNC_OP_AND_FETCH(nand, 4, ll, sc, and, NEG_v0)
+
+#define SYNC_OP_AND_FETCH_EMUL(op, n, inst, neg, amask, vmask) \
+LEAF(__sync_##op##_and_fetch_##n); \
+ SYNC_EMUL_INIT(amask, vmask); \
+ sll $a1, $a1, $t0; /* Align the parameter. */ \
+ and $a1, $a1, $t1; /* Normalize the parameter. */ \
+1: ll $v0, ($a0); \
+ ##inst $v1, $v0, $a1; \
+ ##neg; \
+ and $t3, $v1, $t1; /* Get the new bits. */ \
+ and $v0, $v0, $t2; /* Get the old bits. */ \
+ or $v0, $v0, $t3; /* Combine the result. */ \
+ move $v1, $v0; \
+ sc $v1, ($a0); \
+ beq $v1, $0, 1b; \
+ nop; \
+ j $ra; \
+ srl $v0, $t3, $t0; /* Remove the shift. */ \
+END(__sync_##op##_and_fetch_##n)
+
+SYNC_OP_AND_FETCH_EMUL(add, 2, addu, NO_NEG, 2, 0xffff)
+SYNC_OP_AND_FETCH_EMUL(sub, 2, subu, NO_NEG, 2, 0xffff)
+SYNC_OP_AND_FETCH_EMUL(or, 2, or, NO_NEG, 2, 0xffff)
+SYNC_OP_AND_FETCH_EMUL(and, 2, and, NO_NEG, 2, 0xffff)
+SYNC_OP_AND_FETCH_EMUL(xor, 2, xor, NO_NEG, 2, 0xffff)
+SYNC_OP_AND_FETCH_EMUL(nand, 2, and, NEG_v1, 2, 0xffff)
+
+SYNC_OP_AND_FETCH_EMUL(add, 1, addu, NO_NEG, 3, 0xff)
+SYNC_OP_AND_FETCH_EMUL(sub, 1, subu, NO_NEG, 3, 0xff)
+SYNC_OP_AND_FETCH_EMUL(or, 1, or, NO_NEG, 3, 0xff)
+SYNC_OP_AND_FETCH_EMUL(and, 1, and, NO_NEG, 3, 0xff)
+SYNC_OP_AND_FETCH_EMUL(xor, 1, xor, NO_NEG, 3, 0xff)
+SYNC_OP_AND_FETCH_EMUL(nand, 1, and, NEG_v1, 3, 0xff)
+
+/*
+ * type __sync_bool_compare_and_swap_<N>(type *ptr, type oldv, type newv)
+ */
+
+#define SYNC_BOOL_COMPARE_AND_SWAP(n, ll, sc, trunc) \
+LEAF(__sync_bool_compare_and_swap_##n); \
+ trunc; \
+1: ##ll $v0, ($a0); \
+ bne $v0, $a1, 2f; \
+ move $v1, $a2; \
+ ##sc $v1, ($a0); \
+ beq $v1, $0, 1b; \
+ nop; \
+ j $ra; \
+ li $v0, 1; \
+2: j $ra; \
+ li $v0, 0; \
+END(__sync_bool_compare_and_swap_##n)
+
+SYNC_BOOL_COMPARE_AND_SWAP(8, lld, scd, NO_TRUNC)
+SYNC_BOOL_COMPARE_AND_SWAP(4, ll, sc, TRUNC_32($a1, $t0))
+
+#define SYNC_BOOL_COMPARE_AND_SWAP_EMUL(n, amask, vmask) \
+LEAF(__sync_bool_compare_and_swap_##n); \
+ SYNC_EMUL_INIT(amask, vmask); \
+ /* Align and normalize the parameters. */ \
+ sll $a1, $a1, $t0; \
+ and $a1, $a1, $t1; \
+ sll $a2, $a2, $t0; \
+ and $a2, $a2, $t1; \
+ /* Do the update. */ \
+1: ll $v0, ($a0); \
+ and $v1, $v0, $t1; /* Get the old value. */ \
+ bne $v1, $a1, 2f; \
+ and $v1, $v0, $t2; /* Clear the old value. */ \
+ or $v1, $v1, $a2; /* Insert the new value. */ \
+ sc $v1, ($a0); \
+ beq $v1, $0, 1b; \
+ nop; \
+ j $ra; \
+ li $v0, 1; \
+2: j $ra; \
+ li $v0, 0; \
+END(__sync_bool_compare_and_swap_##n)
+
+SYNC_BOOL_COMPARE_AND_SWAP_EMUL(2, 2, 0xffff)
+SYNC_BOOL_COMPARE_AND_SWAP_EMUL(1, 3, 0xff)
+
+/*
+ * type __sync_val_compare_and_swap_<N>(type *ptr, type oldv, type newv)
+ */
+
+#define SYNC_VAL_COMPARE_AND_SWAP(n, ll, sc, trunc) \
+LEAF(__sync_val_compare_and_swap_##n); \
+ trunc; \
+1: ##ll $v0, ($a0); \
+ bne $v0, $a1, 2f; \
+ move $v1, $a2; \
+ ##sc $v1, ($a0); \
+ beq $v1, $0, 1b; \
+ nop; \
+2: j $ra; \
+ nop; \
+END(__sync_val_compare_and_swap_##n)
+
+SYNC_VAL_COMPARE_AND_SWAP(8, lld, scd, NO_TRUNC)
+SYNC_VAL_COMPARE_AND_SWAP(4, ll, sc, TRUNC_32($a1, $t0))
+
+#define SYNC_VAL_COMPARE_AND_SWAP_EMUL(n, amask, vmask) \
+LEAF(__sync_val_compare_and_swap_##n); \
+ SYNC_EMUL_INIT(amask, vmask); \
+ /* Align and normalize the parameters. */ \
+ sll $a1, $a1, $t0; \
+ and $a1, $a1, $t1; \
+ sll $a2, $a2, $t0; \
+ and $a2, $a2, $t1; \
+ /* Do the update. */ \
+1: ll $v0, ($a0); \
+ and $t3, $v0, $t1; /* Get the old value. */ \
+ bne $t3, $a1, 2f; \
+ and $v1, $v0, $t2; /* Clear the old value. */ \
+ or $v1, $v1, $a2; /* Insert the new value. */ \
+ sc $v1, ($a0); \
+ beq $v1, $0, 1b; \
+ nop; \
+2: j $ra; \
+ srl $v0, $t3, $t0; /* Remove the shift. */ \
+END(__sync_val_compare_and_swap_##n)
+
+SYNC_VAL_COMPARE_AND_SWAP_EMUL(2, 2, 0xffff)
+SYNC_VAL_COMPARE_AND_SWAP_EMUL(1, 3, 0xff)
+
+/*
+ * type __sync_lock_test_and_set_<N>(type *ptr, type value)
+ */
+
+#define SYNC_LOCK_TEST_AND_SET(n, ll, sc) \
+LEAF(__sync_lock_test_and_set_##n); \
+1: move $v1, $a1; \
+ ##ll $v0, ($a0); \
+ ##sc $v1, ($a0); \
+ beq $v1, $0, 1b; \
+ nop; \
+ j $ra; \
+ nop; \
+END(__sync_lock_test_and_set_##n)
+
+SYNC_LOCK_TEST_AND_SET(8, lld, scd)
+SYNC_LOCK_TEST_AND_SET(4, ll, sc)
+
+#define SYNC_LOCK_TEST_AND_SET_EMUL(n, amask, vmask) \
+LEAF(__sync_lock_test_and_set_##n); \
+ SYNC_EMUL_INIT(amask, vmask); \
+ sll $a1, $a1, $t0; /* Align the parameter. */ \
+ and $a1, $a1, $t1; /* Normalize the parameter. */ \
+1: ll $v0, ($a0); \
+ and $v1, $v0, $t2; /* Clear the old value. */ \
+ or $v1, $v1, $a1; /* Insert the new value. */ \
+ sc $v1, ($a0); \
+ beq $v1, $0, 1b; \
+ nop; \
+ and $v0, $v0, $t1; /* Get the old value. */ \
+ j $ra; \
+ srl $v0, $v0, $t0; /* Remove the shift. */ \
+END(__sync_lock_test_and_set_##n)
+
+SYNC_LOCK_TEST_AND_SET_EMUL(2, 2, 0xffff)
+SYNC_LOCK_TEST_AND_SET_EMUL(1, 3, 0xff)
diff --git a/sys/uvm/uvm_device.c b/sys/uvm/uvm_device.c
index 36cb8bf0eb1..c6001ec58b5 100644
--- a/sys/uvm/uvm_device.c
+++ b/sys/uvm/uvm_device.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_device.c,v 1.53 2016/09/16 02:35:42 dlg Exp $ */
+/* $OpenBSD: uvm_device.c,v 1.54 2017/05/21 13:00:53 visa Exp $ */
/* $NetBSD: uvm_device.c,v 1.30 2000/11/25 06:27:59 chs Exp $ */
/*
@@ -42,7 +42,8 @@
#include <uvm/uvm_device.h>
#if defined(__amd64__) || defined(__i386__) || \
- defined(__macppc__) || defined(__sparc64__)
+ defined(__loongson__) || defined(__macppc__) || \
+ defined(__sparc64__)
#include "drm.h"
#endif