NetBSD Problem Report #43688

From khorben@defora.org  Sat Jul 31 00:20:20 2010
Return-Path: <khorben@defora.org>
Received: from mail.netbsd.org (mail.netbsd.org [204.152.190.11])
	by www.NetBSD.org (Postfix) with ESMTP id D58D463BB39
	for <gnats-bugs@gnats.NetBSD.org>; Sat, 31 Jul 2010 00:20:20 +0000 (UTC)
Message-Id: <20100731002015.8C0D9F3@kwarx.defora.lan>
Date: Sat, 31 Jul 2010 02:20:15 +0200 (CEST)
From: Pierre Pronchery <khorben@defora.org>
To: gnats-bugs@gnats.NetBSD.org
Subject: ioperm() is missing on NetBSD/amd64 (patch provided)
X-Send-Pr-Version: 3.95

>Number:         43688
>Category:       port-amd64
>Synopsis:       ioperm() is missing on NetBSD/amd64 (patch provided)
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    port-amd64-maintainer
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Jul 31 00:25:00 +0000 2010
>Closed-Date:    Mon Mar 05 16:27:28 +0000 2018
>Last-Modified:  Mon Mar 05 16:27:28 +0000 2018
>Originator:     Pierre Pronchery
>Release:        NetBSD 5.1_RC2
>Organization:
>Environment:
System: NetBSD kwarx.defora.lan 5.1_RC2 NetBSD 5.1_RC2 (GENERIC) #2: Fri Jun 11 21:15:51 CEST 2010 khorben@kwarx.defora.lan:/usr/obj/sys/arch/amd64/compile/GENERIC amd64
Architecture: x86_64
Machine: amd64
>Description:
On x86-based platforms, the ioperm() allows fine-grained access to "hardware
ports", typically serial and parallel ports managed by the BIOS. These are then
referenced by a port number up to 0x4000, otherwise requiring a call to iopl()
instead (which basically grants or denies access to all the ports at once).
Interaction with the actual device can then be performed with the inb/outb
assembly calls.

These two interfaces are inherently platform-specific, and found on fewer
architectures besides x86. In fact, NetBSD's amd64 port only supports iopl()
nowadays; the patch supplied here adds support for ioperm().

This patch applies on NetBSD 5.1_RC3, I hope it will also apply on -current. In any case, it would also need a manual page for the exact interfaces to ioperm(): x86_64_get_ioperm() and x86_64_set_ioperm(), as illustrated below in psx.c.

>How-To-Repeat:
Try to use ioperm() (or a direct equivalent) on NetBSD/amd64: iopl() has to be
used instead.

I have used the following program to demonstrate the issue, and test my changes;
it is a userland adaptation of a Linux kernel driver, gamecon, supporting NES,
SNES, N64, Multi1, Multi2, and PSX gamepads through the parallel port.


/* $Id: psx.c,v 1.2 2010/07/31 00:04:12 khorben Exp $ */
/* Copyright (c) 2010 Pierre Pronchery <khorben@defora.org> */
/*
 *  Based on the work of Vojtech Pavlik
 * $Id: gamecon.c,v 1.14 2001/04/29 22:42:14 vojtech Exp $
 *  In turn based on the work of:
 *      Andree Borrmann         John Dahlstrom
 *      David Kuder             Nathan Hand
 *
 *  Sponsored by SuSE
 */
/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or 
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * Should you need to contact the original author, you can do so either by
 * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
 * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
 */



#include <sys/types.h>
#include <sys/wait.h>
#include <machine/sysarch.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

/* ioperm */
#ifdef __NetBSD__
int ioperm(unsigned long from, unsigned long num, int permit);
# if defined(__amd64__)
#  define get_ioperm(ports) x86_64_get_ioperm(ports)
#  define set_ioperm(ports) x86_64_set_ioperm(ports)
int x86_64_get_ioperm(unsigned long * ports);
int x86_64_set_ioperm(unsigned long * ports);
# elif defined(__i386__)
#  define get_ioperm(ports) i386_get_ioperm(ports)
#  define set_ioperm(ports) i386_set_ioperm(ports)
int i386_get_ioperm(unsigned long * ports);
int i386_set_ioperm(unsigned long * ports);
# endif
#else
# include <sys/io.h>
#endif


/* constants */
#define D0	0x01
#define D1	0x02
#define D2	0x04
#define D3	0x08
#define D4	0x10
#define D5	0x20
#define D6	0x40
#define D7	0x80

/* PSX */
#define PSX_CLOCK	D2
#define PSX_COMMAND	D0
#define PSX_DELAY	60
#define PSX_ID(x)	((x) >> 4)
#define PSX_LENGTH(x)	((x) & 0x0f)
#define PSX_SELECT	D1
#define PSX_POWER	(D3 | D4 | D5 | D6 | D7)


/* prototypes */
/* assembly routines */
extern unsigned char inb(unsigned short int port);
extern void outb(unsigned short int port, unsigned char value);

/* useful */
static void _udelay(int delay);

static int _psx_command(unsigned short int port, unsigned char * pads, int b);

static unsigned char _read_data(unsigned short int port);
static unsigned char _read_status(unsigned short int port);

static void _write_control(unsigned short int port, unsigned char value);
static void _write_data(unsigned short int port, unsigned char value);

static int _error(char const * message, int ret);
static int _usage(void);


/* functions */
static void _udelay(int delay)
{
	struct timespec ts;

	ts.tv_sec = 0;
	ts.tv_nsec = delay * 1000;
	nanosleep(&ts, NULL);
}


static int _psx_command(unsigned short int port, unsigned char * pads, int b)
{
	size_t i;
	int cmd;
	int data = 0;

#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s(0x%x, 0x%x)\n", __func__, port, b);
#endif
	for(i = 0; i < 8; i++)
	{
		cmd = (b & 1) ? PSX_COMMAND : 0;
		_write_data(port, cmd | PSX_POWER);
		_udelay(PSX_DELAY);
		data |= (_read_status(port) ^ 0x80) & pads[7] ? (1 << i) : 0;
#ifdef DEBUG
		fprintf(stderr, "DEBUG: data=0x%02x\n", data);
#endif
		_write_data(port, cmd | PSX_CLOCK | PSX_POWER);
		_udelay(PSX_DELAY);
		b >>= 1;
	}
#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s(0x%x, 0x%x) => 0x%04x\n", __func__, port, b,
			data);
#endif
	return data;
}


static unsigned char _read_data(unsigned short int port)
{
	unsigned char ret;

	ret = inb(port);
#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s(0x%x) => 0x%02x\n", __func__, port, ret);
#endif
	return ret;
}


static unsigned char _read_status(unsigned short int port)
{
	unsigned char ret;

	ret = inb(port + 0x01);
#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s(0x%x) => 0x%02x, 0x%02x\n", __func__, port,
			ret, ret ^ 0x80);
#endif
	return ret;
}


static int _psx_read_packet(unsigned short int port, unsigned char * pads,
		unsigned char * data)
{
	int i;
	int id;

	_write_data(port, PSX_CLOCK | PSX_SELECT | PSX_POWER);
	_udelay(PSX_DELAY * 2);
	_write_data(port, PSX_CLOCK | PSX_POWER);
	_udelay(PSX_DELAY * 2);

	_psx_command(port, pads, 0x01);
	id = _psx_command(port, pads, 0x42);
#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s() id=0x%02x\n", __func__, id);
#endif
	if(_psx_command(port, pads, 0) == 0x5a)
		for(i = 0; i < PSX_LENGTH(id) * 2; i++)
			data[i] = _psx_command(port, pads, 0x00);
	else
		id = 0;
	_write_data(port, PSX_CLOCK | PSX_SELECT | PSX_POWER);
	return PSX_ID(id);
}


static void _write_control(unsigned short int port, unsigned char value)
{
#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s(0x%x, 0x%02x)\n", __func__, port, value);
#endif
	/* FIXME verify if the value is tolerated */
	outb(port + 0x02, value);
}


static void _write_data(unsigned short int port, unsigned char value)
{
#ifdef DEBUG
	fprintf(stderr, "DEBUG: %s(0x%x, 0x%02x)\n", __func__, port, value);
#endif
	outb(port, value);
}


/* error */
static int _error(char const * message, int ret)
{
	perror(message);
	return ret;
}


/* usage */
static int _usage(void)
{
	fputs("Usage: psx -p port\n", stderr);
	return 1;
}


/* main */
int main(int argc, char * argv[])
{
	int o;
	int port = -1;
	/* unsigned char c; */
	unsigned char pads[8];
	int i;
	unsigned char data[32];
	int id;
	int config[6] = { 0, 7, 0, 0, 0, 0 };
	int gc_status_bits[] = { 0x40, 0x80, 0x20, 0x10, 0x08 };

	while((o = getopt(argc, argv, "p:")) != -1)
		switch(o)
		{
			case 'p':
				port = strtoul(optarg, NULL, 0);
				break;
			default:
				return _usage();
		}
	if(port < 0)
		return _usage();
	if(x86_64_iopl(2) != 0)
		return _error("iopl", 2);
	printf("Port: 0x%x\n", port);
	_write_control(port, 0x04);
	memset(&pads, 0, sizeof(pads));
	for(i = 0; i < 5; i++)
	{
		if(!config[i + 1])
			continue;

		if(config[i + 1] < 1 || config[i + 1] > 7)
			exit(2);

		pads[0] |= gc_status_bits[i];
		pads[config[i + 1]] |= gc_status_bits[i];

		if(pads[7])
		{
			id = _psx_read_packet(port, pads, data);
			printf("ID: 0x%x\n", id);
		}
	}
	/* exit */
	_write_control(port, 0x00);
	return 0;
}


/* ioperm */
#ifdef __NetBSD__
int ioperm(unsigned long from, unsigned long num, int permit)
{
	unsigned long ports[32];
	unsigned long i;

	if(get_ioperm(ports) == -1)
		return -1;
	for(i = from; i < (from + num); i++)
		if(permit)
			ports[i / 32] &= ~(1 << (i % 32));
		else
			ports[i / 32] |= (1 << (i % 32));
	if(set_ioperm(ports) == -1)
		return -1;
	return 0;
}
#endif

>Fix:
Index: lib/libarch/x86_64/Makefile.inc
===================================================================
RCS file: /cvsroot/src/lib/libarch/x86_64/Makefile.inc,v
retrieving revision 1.3
diff -p -u -r1.3 Makefile.inc
--- lib/libarch/x86_64/Makefile.inc	26 Oct 2008 07:05:33 -0000	1.3
+++ lib/libarch/x86_64/Makefile.inc	30 Jul 2010 23:35:56 -0000
@@ -3,7 +3,7 @@
 LD32DIR?=	none

 .if (${MACHINE_ARCH} == "x86_64" && ${LD32DIR} != "i386")
-SRCS+=	x86_64_mtrr.c x86_64_iopl.c
+SRCS+=	x86_64_mtrr.c x86_64_iopl.c x86_64_get_ioperm.c x86_64_set_ioperm.c
 .endif

 MAN+=	x86_64_get_mtrr.2 x86_64_iopl.2
Index: sys/arch/amd64/amd64/genassym.cf
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/amd64/genassym.cf,v
retrieving revision 1.37.4.2
diff -p -u -r1.37.4.2 genassym.cf
--- sys/arch/amd64/amd64/genassym.cf	2 Feb 2009 03:22:55 -0000	1.37.4.2
+++ sys/arch/amd64/amd64/genassym.cf	30 Jul 2010 23:36:05 -0000
@@ -146,6 +146,8 @@ define	L1_SLOT_KERNBASE	pl1_pi(KERNBASE)

 define	PDIR_SLOT_PTE		PDIR_SLOT_PTE

+define	IOMAPSIZE		IOMAPSIZE
+
 define	VM_MAXUSER_ADDRESS	(unsigned long long)VM_MAXUSER_ADDRESS

 define	L_ADDR			offsetof(struct lwp, l_addr)
@@ -189,6 +191,7 @@ define	PCB_RSP0		offsetof(struct pcb, pc
 define	PCB_CR0			offsetof(struct pcb, pcb_cr0)
 define	PCB_ONFAULT		offsetof(struct pcb, pcb_onfault)
 define	PCB_FPCPU		offsetof(struct pcb, pcb_fpcpu)
+define	PCB_IOMAP		offsetof(struct pcb, pcb_iomap)

 define	TF_RDI			offsetof(struct trapframe, tf_rdi)
 define	TF_RSI			offsetof(struct trapframe, tf_rsi)
@@ -237,7 +240,11 @@ define	CPU_INFO_CURLDT		offsetof(struct 
 define	CPU_INFO_IDLELWP	offsetof(struct cpu_info, ci_data.cpu_idlelwp)
 define	CPU_INFO_PMAP		offsetof(struct cpu_info, ci_pmap)
 define	CPU_INFO_CPUMASK	offsetof(struct cpu_info, ci_cpumask)
+define	CPU_INFO_TSS		offsetof(struct cpu_info, ci_tss)
 define	CPU_INFO_RSP0		offsetof(struct cpu_info, ci_tss.tss_rsp0)
+define	CPU_INFO_IOBASE		offsetof(struct cpu_info, ci_tss.tss_iobase)
+define	CPU_INFO_IOMAP		offsetof(struct cpu_info, ci_iomap)
+define	IOMAP_INVALOFF		IOMAP_INVALOFF
 define	CPU_INFO_NSYSCALL	offsetof(struct cpu_info, ci_data.cpu_nsyscall)
 define	CPU_INFO_NTRAP		offsetof(struct cpu_info, ci_data.cpu_ntrap)
 define	CPU_INFO_CURPRIORITY	offsetof(struct cpu_info, ci_schedstate.spc_curpriority)
Index: sys/arch/amd64/amd64/locore.S
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/amd64/locore.S,v
retrieving revision 1.47.8.4
diff -p -u -r1.47.8.4 locore.S
--- sys/arch/amd64/amd64/locore.S	22 Apr 2010 20:02:48 -0000	1.47.8.4
+++ sys/arch/amd64/amd64/locore.S	30 Jul 2010 23:36:05 -0000
@@ -955,6 +955,13 @@ ENTRY(cpu_switchto)
 	testl	$LW_SYSTEM,L_FLAG(%r12)
 	jnz	4f

+	/* Switch I/O bitmap */
+	movq	PCB_IOMAP(%rbx),%rax
+/*	orq	%rax,%rax */
+	jnz,pn	.Lcopy_iobitmap
+	movl	$(IOMAP_INVALOFF << 16),CPUVAR(IOBASE)
+.Liobitmap_done:
+
 	/* Is this process using RAS (restartable atomic sequences)? */
 	movq	L_PROC(%r12),%rdi
 	cmpq	$0,P_RASLIST(%rdi)
@@ -1003,6 +1010,21 @@ ENTRY(cpu_switchto)
 	movq	%rax,TF_RIP(%rbx)
 	jmp	2b

+.Lcopy_iobitmap:
+	/* Copy I/O bitmap. */
+	movq	$(IOMAPSIZE/8),%rcx
+	pushq	%rsi
+	pushq	%rdi
+	movq	%rax,%rsi		/* pcb_iomap */
+	movq	CPUVAR(SELF),%rdi
+	leaq	CPU_INFO_IOMAP(%rdi),%rdi
+	rep
+	movsq
+	popq	%rdi
+	popq	%rsi
+	movq	$((CPU_INFO_IOMAP - CPU_INFO_TSS) << 16),CPUVAR(IOBASE)
+	jmp	.Liobitmap_done
+
 /*
  * void savectx(struct pcb *pcb);
  *
Index: sys/arch/amd64/amd64/vm_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/amd64/Attic/vm_machdep.c,v
retrieving revision 1.34.4.1
diff -p -u -r1.34.4.1 vm_machdep.c
--- sys/arch/amd64/amd64/vm_machdep.c	16 Feb 2009 03:04:38 -0000	1.34.4.1
+++ sys/arch/amd64/amd64/vm_machdep.c	30 Jul 2010 23:36:05 -0000
@@ -179,6 +179,8 @@ cpu_lwp_fork(struct lwp *l1, struct lwp 

 	pcb->pcb_rsp0 = (USER_TO_UAREA(l2->l_addr) + KSTACK_SIZE - 16) & ~0xf;

+	pcb->pcb_iomap = NULL;
+
 	/*
 	 * Copy the trapframe.
 	 */
Index: sys/arch/amd64/include/pcb.h
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/include/pcb.h,v
retrieving revision 1.15
diff -p -u -r1.15 pcb.h
--- sys/arch/amd64/include/pcb.h	26 Oct 2008 00:08:15 -0000	1.15
+++ sys/arch/amd64/include/pcb.h	30 Jul 2010 23:36:06 -0000
@@ -104,6 +104,7 @@ struct pcb {
 	uint64_t  pcb_gs;
 	uint64_t  pcb_fs;
 	int pcb_iopl;
+	char	*pcb_iomap;		/* I/O permission bitmap */
 };

 /*    
Index: sys/arch/x86/x86/sys_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/x86/sys_machdep.c,v
retrieving revision 1.15.8.1
diff -p -u -r1.15.8.1 sys_machdep.c
--- sys/arch/x86/x86/sys_machdep.c	4 Apr 2009 17:39:09 -0000	1.15.8.1
+++ sys/arch/x86/x86/sys_machdep.c	30 Jul 2010 23:36:15 -0000
@@ -71,7 +71,11 @@ __KERNEL_RCSID(0, "$NetBSD: sys_machdep.
 #undef	USER_LDT
 #undef	PERFCTRS
 #undef	VM86
-#undef	IOPERM
+#if 0 /* khorben */
+# undef IOPERM
+#else
+# define IOPERM
+#endif
 #else
 #if defined(XEN)
 #undef	IOPERM

>Release-Note:

>Audit-Trail:
From: Pierre Pronchery <khorben@defora.org>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: port-amd64/43688: ioperm() is missing on NetBSD/amd64 (patch
 provided)
Date: Sat, 31 Jul 2010 02:37:07 +0200

 This is a multi-part message in MIME format.
 --------------020908070203000902050605
 Content-Type: text/plain; charset=ISO-8859-1
 Content-Transfer-Encoding: 7bit

 I just realized it's missing two files in lib/libarch/x86_64; they are
 attached here.

 HTH,
 -- 
 khorben

 --------------020908070203000902050605
 Content-Type: text/plain;
  name="x86_64_get_ioperm.c"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
  filename="x86_64_get_ioperm.c"

 /*	$NetBSD: i386_get_ioperm.c,v 1.6 2008/04/28 20:22:55 martin Exp $	*/

 /*-
  * Copyright (c) 1996 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
  * by John T. Kohl and Charles M. Hannum.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */

 #include <sys/cdefs.h>
 #include <sys/types.h>

 #include <machine/sysarch.h>

 int x86_64_get_ioperm(u_long *);

 int
 x86_64_get_ioperm(iomap)
 	u_long *iomap;
 {
 	struct x86_64_get_ioperm_args p;

 	p.iomap = iomap;

 	return sysarch(X86_64_GET_IOPERM, &p);
 }

 --------------020908070203000902050605
 Content-Type: text/plain;
  name="x86_64_set_ioperm.c"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
  filename="x86_64_set_ioperm.c"

 /*	$NetBSD: i386_set_ioperm.c,v 1.6 2008/04/28 20:22:55 martin Exp $	*/

 /*-
  * Copyright (c) 1996 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
  * by John T. Kohl and Charles M. Hannum.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */

 #include <sys/cdefs.h>
 #include <sys/types.h>

 #include <machine/sysarch.h>

 int x86_64_set_ioperm(u_long *);

 int
 x86_64_set_ioperm(iomap)
 	u_long *iomap;
 {
 	struct x86_64_set_ioperm_args p;

 	p.iomap = iomap;

 	return sysarch(X86_64_SET_IOPERM, &p);
 }

 --------------020908070203000902050605--

State-Changed-From-To: open->closed
State-Changed-By: maxv@NetBSD.org
State-Changed-When: Mon, 05 Mar 2018 16:27:28 +0000
State-Changed-Why:
No ioperm on amd64, bug friendly and little interest, ok khorben@


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.43 2018/01/16 07:36:43 maya Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2017 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.