diff options
author | Visa Hankala <visa@cvs.openbsd.org> | 2017-05-21 13:00:54 +0000 |
---|---|---|
committer | Visa Hankala <visa@cvs.openbsd.org> | 2017-05-21 13:00:54 +0000 |
commit | 799df8f1ea252a453c6519ce1108d5bb52ca6109 (patch) | |
tree | 09db6f2494a20adffaa9a5acbdd05425f5ef3761 | |
parent | ed3a9a1e17cf4ba2d1a8476904c0e1e989ac1aa1 (diff) |
Enable radeondrm(4) on loongson to get accelerated graphics
with the RS780E chipset.
OK kettenis@, jsg@
-rw-r--r-- | etc/etc.loongson/MAKEDEV.md | 4 | ||||
-rw-r--r-- | sys/arch/loongson/conf/GENERIC | 5 | ||||
-rw-r--r-- | sys/arch/loongson/include/autoconf.h | 3 | ||||
-rw-r--r-- | sys/arch/loongson/include/pmon.h | 3 | ||||
-rw-r--r-- | sys/arch/loongson/include/vmparam.h | 4 | ||||
-rw-r--r-- | sys/arch/loongson/loongson/conf.c | 16 | ||||
-rw-r--r-- | sys/arch/loongson/loongson/generic3a_machdep.c | 7 | ||||
-rw-r--r-- | sys/arch/loongson/loongson/machdep.c | 3 | ||||
-rw-r--r-- | sys/arch/loongson/loongson/pmon.c | 12 | ||||
-rw-r--r-- | sys/arch/mips64/conf/files.mips64 | 3 | ||||
-rw-r--r-- | sys/dev/pci/drm/radeon/radeon_bios.c | 14 | ||||
-rw-r--r-- | sys/kern/kern_pledge.c | 5 | ||||
-rw-r--r-- | sys/lib/libkern/arch/mips64/sync.S | 317 | ||||
-rw-r--r-- | sys/uvm/uvm_device.c | 5 |
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 |