⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ioperm.c

📁 Glibc 2.3.2源代码(解压后有100多M)
💻 C
字号:
/* Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.   This file is part of the GNU C Library.   Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.   The GNU C Library is free software; you can redistribute it and/or   modify it under the terms of the GNU Lesser General Public   License as published by the Free Software Foundation; either   version 2.1 of the License, or (at your option) any later version.   The GNU C Library 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   Lesser General Public License for more details.   You should have received a copy of the GNU Lesser General Public   License along with the GNU C Library; if not, write to the Free   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA   02111-1307 USA.  *//* I/O access is restricted to ISA port space (ports 0..65535).   Modern devices hopefully are sane enough not to put any performance   critical registers in i/o space.   On the first call to ioperm() or iopl(), the entire (E)ISA port   space is mapped into the virtual address space at address io.base.   mprotect() calls are then used to enable/disable access to ports.   Per 4KB page, there are 4 I/O ports.  */#include <errno.h>#include <fcntl.h>#include <ctype.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/mman.h>#define MAX_PORT	0x10000/* * Memory fence w/accept.  This should never be used in code that is * not IA-64 specific. */#define __ia64_mf_a()	__asm__ __volatile__ ("mf.a" ::: "memory")static struct  {    unsigned long int base;    unsigned long int page_mask;  }io;__inline__ unsigned long intio_offset (unsigned long int port){	return ((port >> 2) << 12) | (port & 0xfff);}int_ioperm (unsigned long int from, unsigned long int num, int turn_on){#if 0  unsigned long int addr, len, base;#endif  unsigned long int base;  int prot;  /* this test isn't as silly as it may look like; consider overflows! */  if (from >= MAX_PORT || from + num > MAX_PORT)    {      __set_errno (EINVAL);      return -1;    }  if (turn_on)    {      if (!io.base)	{	  unsigned long phys_io_base, len;	  int fd;	  io.page_mask = ~(__getpagesize() - 1);	  /* get I/O base physical address from ar.k0 as per PRM: */	  __asm__ ("mov %0=ar.k0" : "=r"(phys_io_base));	  /* The O_SYNC flag tells the /dev/mem driver to map the             memory uncached: */	  fd = __open ("/dev/mem", O_RDWR | O_SYNC);	  if (fd < 0)	    return -1;	  len = io_offset (MAX_PORT);#if 1	  /* see comment below */	  base = (unsigned long int) __mmap (0, len, PROT_READ | PROT_WRITE, MAP_SHARED,						fd, phys_io_base);#else	  base = (unsigned long int) __mmap (0, len, PROT_NONE, MAP_SHARED,						fd, phys_io_base);#endif	  __close (fd);	  if ((long) base == -1)	    return -1;	  io.base = base;	}      prot = PROT_READ | PROT_WRITE;    }  else    {      if (!io.base)	return 0;	/* never was turned on... */      prot = PROT_NONE;    }#if 0  /* We can't do mprotect because that would cause us to lose the     uncached flag that the /dev/mem driver turned on.  A MAP_UNCACHED     flag seems so much cleaner...  */  addr = (io.base + io_offset (from)) & io.page_mask;  len  = io.base + io_offset (from + num) - addr;  return mprotect ((void *) addr, len, prot);#else  return 0;#endif}int_iopl (unsigned int level){  if (level > 3)    {      __set_errno (EINVAL);      return -1;    }  if (level)    return _ioperm (0, MAX_PORT, 1);  return 0;}unsigned int_inb (unsigned long int port){  volatile unsigned char *addr = (void *) io.base + io_offset (port);  unsigned char ret;  ret = *addr;  __ia64_mf_a();  return ret;}unsigned int_inw (unsigned long int port){  volatile unsigned short *addr = (void *) io.base + io_offset (port);  unsigned short ret;  ret = *addr;  __ia64_mf_a();  return ret;}unsigned int_inl (unsigned long int port){  volatile unsigned int *addr = (void *) io.base + io_offset (port);  unsigned int ret;  ret = *addr;  __ia64_mf_a();  return ret;}void_outb (unsigned char val, unsigned long int port){  volatile unsigned char *addr = (void *) io.base + io_offset (port);  *addr = val;  __ia64_mf_a();}void_outw (unsigned short val, unsigned long int port){  volatile unsigned short *addr = (void *) io.base + io_offset (port);  *addr = val;  __ia64_mf_a();}void_outl (unsigned int val, unsigned long int port){  volatile unsigned int *addr = (void *) io.base + io_offset (port);  *addr = val;  __ia64_mf_a();}weak_alias (_ioperm, ioperm);weak_alias (_iopl, iopl);weak_alias (_inb, inb);weak_alias (_inw, inw);weak_alias (_inl, inl);weak_alias (_outb, outb);weak_alias (_outw, outw);weak_alias (_outl, outl);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -