OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [mips/] [sni/] [io.c] - Rev 1765

Compare with Previous | Blame | View Log

/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Low level I/O functions for SNI.
 */
#include <linux/string.h>
#include <linux/spinlock.h>
#include <asm/addrspace.h>
#include <asm/system.h>
#include <asm/sni.h>
 
/*
 * Urgs...  We only can see a 16mb window of the 4gb EISA address space
 * at PCIMT_EISA_BASE.  Maladia segmentitis ...
 *
 * To avoid locking and all the related headacke we implement this such
 * that accessing the bus address space nests, so we're treating this
 * correctly even for interrupts.  This is going to suck seriously for
 * the SMP members of the RM family.
 *
 * Making things worse the PCIMT_CSMAPISA register resides on the X bus with
 * it's unbeatable 1.4 mb/s transfer rate.
 */
 
static inline void eisa_map(unsigned long address)
{
	unsigned char upper;
 
	upper = address >> 24;
	*(volatile unsigned char *)PCIMT_CSMAPISA = ~upper;
}
 
#define save_eisa_map()							\
	(*(volatile unsigned char *)PCIMT_CSMAPISA)
#define restore_eisa_map(val)						\
	do { (*(volatile unsigned char *)PCIMT_CSMAPISA) = val; } while(0)
 
static unsigned char sni_readb(unsigned long addr)
{
	unsigned char res;
	unsigned int save_map;
 
	save_map = save_eisa_map();
	eisa_map(addr);
	addr &= 0xffffff;
	res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr);
	restore_eisa_map(save_map);
 
	return res;
}
 
static unsigned short sni_readw(unsigned long addr)
{
	unsigned short res;
	unsigned int save_map;
 
	save_map = save_eisa_map();
	eisa_map(addr);
	addr &= 0xffffff;
	res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr);
	restore_eisa_map(save_map);
 
	return res;
}
 
static unsigned int sni_readl(unsigned long addr)
{
	unsigned int res;
	unsigned int save_map;
 
	save_map = save_eisa_map();
	eisa_map(addr);
	addr &= 0xffffff;
	res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr);
	restore_eisa_map(save_map);
 
	return res;
}
 
static void sni_writeb(unsigned char val, unsigned long addr)
{
	unsigned int save_map;
 
	save_map = save_eisa_map();
	eisa_map(addr);
	addr &= 0xffffff;
	*(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val;
	restore_eisa_map(save_map);
}
 
static void sni_writew(unsigned short val, unsigned long addr)
{
	unsigned int save_map;
 
	save_map = save_eisa_map();
	eisa_map(addr);
	addr &= 0xffffff;
	*(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val;
	restore_eisa_map(save_map);
}
 
static void sni_writel(unsigned int val, unsigned long addr)
{
	unsigned int save_map;
 
	save_map = save_eisa_map();
	eisa_map(addr);
	addr &= 0xffffff;
	*(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val;
	restore_eisa_map(save_map);
}
 
static void sni_memset_io(unsigned long addr, int val, unsigned long len)
{
	unsigned long waddr;
	unsigned int save_map;
 
	save_map = save_eisa_map();
	waddr = PCIMT_EISA_BASE | (addr & 0xffffff);
	while(len) {
		unsigned long fraglen;
 
		fraglen = (~addr + 1) & 0xffffff;
		fraglen = (fraglen < len) ? fraglen : len;
		eisa_map(addr);
		memset((char *)waddr, val, fraglen);
		addr += fraglen;
		waddr = waddr + fraglen - 0x1000000;
		len -= fraglen;
	}
	restore_eisa_map(save_map);
}
 
static void sni_memcpy_fromio(unsigned long to, unsigned long from, unsigned long len)
{
	unsigned long waddr;
	unsigned int save_map;
 
	save_map = save_eisa_map();
	waddr = PCIMT_EISA_BASE | (from & 0xffffff);
	while(len) {
		unsigned long fraglen;
 
		fraglen = (~from + 1) & 0xffffff;
		fraglen = (fraglen < len) ? fraglen : len;
		eisa_map(from);
		memcpy((void *)to, (void *)waddr, fraglen);
		to += fraglen;
		from += fraglen;
		waddr = waddr + fraglen - 0x1000000;
		len -= fraglen;
	}
	restore_eisa_map(save_map);
}
 
static void sni_memcpy_toio(unsigned long to, unsigned long from, unsigned long len)
{
	unsigned long waddr;
	unsigned int save_map;
 
	save_map = save_eisa_map();
	waddr = PCIMT_EISA_BASE | (to & 0xffffff);
	while(len) {
		unsigned long fraglen;
 
		fraglen = (~to + 1) & 0xffffff;
		fraglen = (fraglen < len) ? fraglen : len;
		eisa_map(to);
		memcpy((char *)to + PCIMT_EISA_BASE, (void *)from, fraglen);
		to += fraglen;
		from += fraglen;
		waddr = waddr + fraglen - 0x1000000;
		len -= fraglen;
	}
	restore_eisa_map(save_map);
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.