1#ifndef __ALPHA_IO_H
2#define __ALPHA_IO_H
3
4/* We don't use IO slowdowns on the Alpha, but.. */
5#define __SLOW_DOWN_IO	do { } while (0)
6#define SLOW_DOWN_IO	do { } while (0)
7
8/*
9 * Virtual -> physical identity mapping starts at this offset
10 */
11#ifdef USE_48_BIT_KSEG
12#define IDENT_ADDR     0xffff800000000000
13#else
14#define IDENT_ADDR     0xfffffc0000000000
15#endif
16
17#ifdef __KERNEL__
18#include <linux/config.h>
19#include <linux/kernel.h>
20#include <asm/system.h>
21#include <asm/machvec.h>
22
23/*
24 * We try to avoid hae updates (thus the cache), but when we
25 * do need to update the hae, we need to do it atomically, so
26 * that any interrupts wouldn't get confused with the hae
27 * register not being up-to-date with respect to the hardware
28 * value.
29 */
30static inline void __set_hae(unsigned long new_hae)
31{
32	unsigned long flags;
33	__save_and_cli(flags);
34
35	alpha_mv.hae_cache = new_hae;
36	*alpha_mv.hae_register = new_hae;
37	mb();
38	/* Re-read to make sure it was written.  */
39	new_hae = *alpha_mv.hae_register;
40
41	__restore_flags(flags);
42}
43
44static inline void set_hae(unsigned long new_hae)
45{
46	if (new_hae != alpha_mv.hae_cache)
47		__set_hae(new_hae);
48}
49
50/*
51 * Change virtual addresses to physical addresses and vv.
52 */
53static inline unsigned long virt_to_phys(void *address)
54{
55	return (unsigned long)address - IDENT_ADDR;
56}
57
58static inline void * phys_to_virt(unsigned long address)
59{
60	return (void *) (address + IDENT_ADDR);
61}
62
63#define page_to_phys(page)	PAGE_TO_PA(page)
64
65/*
66 * Change addresses as seen by the kernel (virtual) to addresses as
67 * seen by a device (bus), and vice versa.
68 *
69 * Note that this only works for a limited range of kernel addresses,
70 * and very well may not span all memory.  Consider this interface
71 * deprecated in favour of the mapping functions in <asm/pci.h>.
72 */
73extern unsigned long __direct_map_base;
74extern unsigned long __direct_map_size;
75
76static inline unsigned long virt_to_bus(void *address)
77{
78	unsigned long phys = virt_to_phys(address);
79	unsigned long bus = phys + __direct_map_base;
80	return phys <= __direct_map_size ? bus : 0;
81}
82
83static inline void *bus_to_virt(unsigned long address)
84{
85	void *virt;
86
87	/* This check is a sanity check but also ensures that bus address 0
88	   maps to virtual address 0 which is useful to detect null pointers
89	   (the NCR driver is much simpler if NULL pointers are preserved).  */
90	address -= __direct_map_base;
91	virt = phys_to_virt(address);
92	return (long)address <= 0 ? NULL : virt;
93}
94
95#else /* !__KERNEL__ */
96
97/*
98 * Define actual functions in private name-space so it's easier to
99 * accommodate things like XFree or svgalib that like to define their
100 * own versions of inb etc.
101 */
102extern void __sethae (unsigned long addr);	/* syscall */
103extern void _sethae (unsigned long addr);	/* cached version */
104
105#endif /* !__KERNEL__ */
106
107/*
108 * There are different chipsets to interface the Alpha CPUs to the world.
109 */
110
111#ifdef __KERNEL__
112#ifdef CONFIG_ALPHA_GENERIC
113
114/* In a generic kernel, we always go through the machine vector.  */
115
116# define __inb(p)	alpha_mv.mv_inb((unsigned long)(p))
117# define __inw(p)	alpha_mv.mv_inw((unsigned long)(p))
118# define __inl(p)	alpha_mv.mv_inl((unsigned long)(p))
119# define __outb(x,p)	alpha_mv.mv_outb((x),(unsigned long)(p))
120# define __outw(x,p)	alpha_mv.mv_outw((x),(unsigned long)(p))
121# define __outl(x,p)	alpha_mv.mv_outl((x),(unsigned long)(p))
122
123# define __readb(a)	alpha_mv.mv_readb((unsigned long)(a))
124# define __readw(a)	alpha_mv.mv_readw((unsigned long)(a))
125# define __readl(a)	alpha_mv.mv_readl((unsigned long)(a))
126# define __readq(a)	alpha_mv.mv_readq((unsigned long)(a))
127# define __writeb(v,a)	alpha_mv.mv_writeb((v),(unsigned long)(a))
128# define __writew(v,a)	alpha_mv.mv_writew((v),(unsigned long)(a))
129# define __writel(v,a)	alpha_mv.mv_writel((v),(unsigned long)(a))
130# define __writeq(v,a)	alpha_mv.mv_writeq((v),(unsigned long)(a))
131
132# define __ioremap(a,s)	alpha_mv.mv_ioremap((unsigned long)(a),(s))
133# define __iounmap(a)   alpha_mv.mv_iounmap((unsigned long)(a))
134# define __is_ioaddr(a)	alpha_mv.mv_is_ioaddr((unsigned long)(a))
135
136# define inb		__inb
137# define inw		__inw
138# define inl		__inl
139# define outb		__outb
140# define outw		__outw
141# define outl		__outl
142
143# define __raw_readb	__readb
144# define __raw_readw	__readw
145# define __raw_readl	__readl
146# define __raw_readq	__readq
147# define __raw_writeb	__writeb
148# define __raw_writew	__writew
149# define __raw_writel	__writel
150# define __raw_writeq	__writeq
151
152#else
153
154/* Control how and what gets defined within the core logic headers.  */
155#define __WANT_IO_DEF
156
157#if defined(CONFIG_ALPHA_APECS)
158# include <asm/core_apecs.h>
159#elif defined(CONFIG_ALPHA_CIA)
160# include <asm/core_cia.h>
161#elif defined(CONFIG_ALPHA_IRONGATE)
162# include <asm/core_irongate.h>
163#elif defined(CONFIG_ALPHA_JENSEN)
164# include <asm/jensen.h>
165#elif defined(CONFIG_ALPHA_LCA)
166# include <asm/core_lca.h>
167#elif defined(CONFIG_ALPHA_MCPCIA)
168# include <asm/core_mcpcia.h>
169#elif defined(CONFIG_ALPHA_POLARIS)
170# include <asm/core_polaris.h>
171#elif defined(CONFIG_ALPHA_T2)
172# include <asm/core_t2.h>
173#elif defined(CONFIG_ALPHA_TSUNAMI)
174# include <asm/core_tsunami.h>
175#elif defined(CONFIG_ALPHA_TITAN)
176# include <asm/core_titan.h>
177#elif defined(CONFIG_ALPHA_WILDFIRE)
178# include <asm/core_wildfire.h>
179#else
180#error "What system is this?"
181#endif
182
183#undef __WANT_IO_DEF
184
185#endif /* GENERIC */
186#endif /* __KERNEL__ */
187
188/*
189 * The convention used for inb/outb etc. is that names starting with
190 * two underscores are the inline versions, names starting with a
191 * single underscore are proper functions, and names starting with a
192 * letter are macros that map in some way to inline or proper function
193 * versions.  Not all that pretty, but before you change it, be sure
194 * to convince yourself that it won't break anything (in particular
195 * module support).
196 */
197extern u8		_inb (unsigned long port);
198extern u16		_inw (unsigned long port);
199extern u32		_inl (unsigned long port);
200extern void		_outb (u8 b,unsigned long port);
201extern void		_outw (u16 w,unsigned long port);
202extern void		_outl (u32 l,unsigned long port);
203extern u8		_readb(unsigned long addr);
204extern u16		_readw(unsigned long addr);
205extern u32		_readl(unsigned long addr);
206extern u64		_readq(unsigned long addr);
207extern void		_writeb(u8 b, unsigned long addr);
208extern void		_writew(u16 b, unsigned long addr);
209extern void		_writel(u32 b, unsigned long addr);
210extern void		_writeq(u64 b, unsigned long addr);
211
212#ifdef __KERNEL__
213/*
214 * The platform header files may define some of these macros to use
215 * the inlined versions where appropriate.  These macros may also be
216 * redefined by userlevel programs.
217 */
218#ifndef inb
219# define inb(p)		_inb(p)
220#endif
221#ifndef inw
222# define inw(p)		_inw(p)
223#endif
224#ifndef inl
225# define inl(p)		_inl(p)
226#endif
227#ifndef outb
228# define outb(b,p)	_outb((b),(p))
229#endif
230#ifndef outw
231# define outw(w,p)	_outw((w),(p))
232#endif
233#ifndef outl
234# define outl(l,p)	_outl((l),(p))
235#endif
236
237#ifndef inb_p
238# define inb_p		inb
239#endif
240#ifndef inw_p
241# define inw_p		inw
242#endif
243#ifndef inl_p
244# define inl_p		inl
245#endif
246
247#ifndef outb_p
248# define outb_p		outb
249#endif
250#ifndef outw_p
251# define outw_p		outw
252#endif
253#ifndef outl_p
254# define outl_p		outl
255#endif
256
257#define IO_SPACE_LIMIT 0xffff
258
259#else
260
261/* Userspace declarations.  Kill in 2.5. */
262
263extern unsigned int	inb(unsigned long port);
264extern unsigned int	inw(unsigned long port);
265extern unsigned int	inl(unsigned long port);
266extern void		outb(unsigned char b,unsigned long port);
267extern void		outw(unsigned short w,unsigned long port);
268extern void		outl(unsigned int l,unsigned long port);
269extern unsigned long	readb(unsigned long addr);
270extern unsigned long	readw(unsigned long addr);
271extern unsigned long	readl(unsigned long addr);
272extern void		writeb(unsigned char b, unsigned long addr);
273extern void		writew(unsigned short b, unsigned long addr);
274extern void		writel(unsigned int b, unsigned long addr);
275
276#endif /* __KERNEL__ */
277
278#ifdef __KERNEL__
279
280/*
281 * On Alpha, we have the whole of I/O space mapped at all times, but
282 * at odd and sometimes discontinuous addresses.  Note that the
283 * discontinuities are all across busses, so we need not care for that
284 * for any one device.
285 *
286 * The DRM drivers need to be able to map contiguously a (potentially)
287 * discontiguous set of I/O pages. This set of pages is scatter-gather
288 * mapped contiguously from the perspective of the bus, but we can't
289 * directly access DMA addresses from the CPU, these addresses need to
290 * have a real ioremap. Therefore, iounmap and the size argument to
291 * ioremap are needed to give the platforms the ability to fully implement
292 * ioremap.
293 *
294 * Map the I/O space address into the kernel's virtual address space.
295 */
296static inline void * ioremap(unsigned long offset, unsigned long size)
297{
298	return (void *) __ioremap(offset, size);
299}
300
301static inline void iounmap(void *addr)
302{
303	__iounmap(addr);
304}
305
306static inline void * ioremap_nocache(unsigned long offset, unsigned long size)
307{
308	return ioremap(offset, size);
309}
310
311/* Indirect back to the macros provided.  */
312
313extern u8		___raw_readb(unsigned long addr);
314extern u16		___raw_readw(unsigned long addr);
315extern u32		___raw_readl(unsigned long addr);
316extern u64		___raw_readq(unsigned long addr);
317extern void		___raw_writeb(u8 b, unsigned long addr);
318extern void		___raw_writew(u16 b, unsigned long addr);
319extern void		___raw_writel(u32 b, unsigned long addr);
320extern void		___raw_writeq(u64 b, unsigned long addr);
321
322#ifdef __raw_readb
323# define readb(a)	({ u8 r_ = __raw_readb(a); mb(); r_; })
324#endif
325#ifdef __raw_readw
326# define readw(a)	({ u16 r_ = __raw_readw(a); mb(); r_; })
327#endif
328#ifdef __raw_readl
329# define readl(a)	({ u32 r_ = __raw_readl(a); mb(); r_; })
330#endif
331#ifdef __raw_readq
332# define readq(a)	({ u64 r_ = __raw_readq(a); mb(); r_; })
333#endif
334
335#ifdef __raw_writeb
336# define writeb(v,a)	({ __raw_writeb((v),(a)); mb(); })
337#endif
338#ifdef __raw_writew
339# define writew(v,a)	({ __raw_writew((v),(a)); mb(); })
340#endif
341#ifdef __raw_writel
342# define writel(v,a)	({ __raw_writel((v),(a)); mb(); })
343#endif
344#ifdef __raw_writeq
345# define writeq(v,a)	({ __raw_writeq((v),(a)); mb(); })
346#endif
347
348#ifndef __raw_readb
349# define __raw_readb(a)	___raw_readb((unsigned long)(a))
350#endif
351#ifndef __raw_readw
352# define __raw_readw(a)	___raw_readw((unsigned long)(a))
353#endif
354#ifndef __raw_readl
355# define __raw_readl(a)	___raw_readl((unsigned long)(a))
356#endif
357#ifndef __raw_readq
358# define __raw_readq(a)	___raw_readq((unsigned long)(a))
359#endif
360
361#ifndef __raw_writeb
362# define __raw_writeb(v,a)  ___raw_writeb((v),(unsigned long)(a))
363#endif
364#ifndef __raw_writew
365# define __raw_writew(v,a)  ___raw_writew((v),(unsigned long)(a))
366#endif
367#ifndef __raw_writel
368# define __raw_writel(v,a)  ___raw_writel((v),(unsigned long)(a))
369#endif
370#ifndef __raw_writeq
371# define __raw_writeq(v,a)  ___raw_writeq((v),(unsigned long)(a))
372#endif
373
374#ifndef readb
375# define readb(a)	_readb((unsigned long)(a))
376#endif
377#ifndef readw
378# define readw(a)	_readw((unsigned long)(a))
379#endif
380#ifndef readl
381# define readl(a)	_readl((unsigned long)(a))
382#endif
383#ifndef readq
384# define readq(a)	_readq((unsigned long)(a))
385#endif
386
387#ifndef writeb
388# define writeb(v,a)	_writeb((v),(unsigned long)(a))
389#endif
390#ifndef writew
391# define writew(v,a)	_writew((v),(unsigned long)(a))
392#endif
393#ifndef writel
394# define writel(v,a)	_writel((v),(unsigned long)(a))
395#endif
396#ifndef writeq
397# define writeq(v,a)	_writeq((v),(unsigned long)(a))
398#endif
399
400/*
401 * String version of IO memory access ops:
402 */
403extern void _memcpy_fromio(void *, unsigned long, long);
404extern void _memcpy_toio(unsigned long, const void *, long);
405extern void _memset_c_io(unsigned long, unsigned long, long);
406
407#define memcpy_fromio(to,from,len) \
408  _memcpy_fromio((to),(unsigned long)(from),(len))
409#define memcpy_toio(to,from,len) \
410  _memcpy_toio((unsigned long)(to),(from),(len))
411#define memset_io(addr,c,len) \
412  _memset_c_io((unsigned long)(addr),0x0101010101010101UL*(u8)(c),(len))
413
414#define __HAVE_ARCH_MEMSETW_IO
415#define memsetw_io(addr,c,len) \
416  _memset_c_io((unsigned long)(addr),0x0001000100010001UL*(u16)(c),(len))
417
418/*
419 * String versions of in/out ops:
420 */
421extern void insb (unsigned long port, void *dst, unsigned long count);
422extern void insw (unsigned long port, void *dst, unsigned long count);
423extern void insl (unsigned long port, void *dst, unsigned long count);
424extern void outsb (unsigned long port, const void *src, unsigned long count);
425extern void outsw (unsigned long port, const void *src, unsigned long count);
426extern void outsl (unsigned long port, const void *src, unsigned long count);
427
428
429#define eth_io_copy_and_sum(skb,src,len,unused) \
430  memcpy_fromio((skb)->data,(src),(len))
431
432static inline int
433check_signature(unsigned long io_addr, const unsigned char *signature,
434		int length)
435{
436	int retval = 0;
437	do {
438		if (readb(io_addr) != *signature)
439			goto out;
440		io_addr++;
441		signature++;
442		length--;
443	} while (length);
444	retval = 1;
445out:
446	return retval;
447}
448
449
450/*
451 * ISA space is mapped to some machine-specific location on Alpha.
452 * Call into the existing hooks to get the address translated.
453 */
454#define isa_readb(a)			readb(__ioremap((a),1))
455#define isa_readw(a)			readw(__ioremap((a),2))
456#define isa_readl(a)			readl(__ioremap((a),4))
457#define isa_writeb(b,a)			writeb((b),__ioremap((a),1))
458#define isa_writew(w,a)			writew((w),__ioremap((a),2))
459#define isa_writel(l,a)			writel((l),__ioremap((a),4))
460#define isa_memset_io(a,b,c)		memset_io(__ioremap((a),(c)),(b),(c))
461#define isa_memcpy_fromio(a,b,c)	memcpy_fromio((a),__ioremap((b),(c)),(c))
462#define isa_memcpy_toio(a,b,c)		memcpy_toio(__ioremap((a),(c)),(b),(c))
463
464static inline int
465isa_check_signature(unsigned long io_addr, const unsigned char *signature,
466		int length)
467{
468	int retval = 0;
469	do {
470		if (isa_readb(io_addr) != *signature)
471			goto out;
472		io_addr++;
473		signature++;
474		length--;
475	} while (length);
476	retval = 1;
477out:
478	return retval;
479}
480
481
482/*
483 * The Alpha Jensen hardware for some rather strange reason puts
484 * the RTC clock at 0x170 instead of 0x70. Probably due to some
485 * misguided idea about using 0x70 for NMI stuff.
486 *
487 * These defines will override the defaults when doing RTC queries
488 */
489
490#ifdef CONFIG_ALPHA_GENERIC
491# define RTC_PORT(x)	((x) + alpha_mv.rtc_port)
492#else
493# ifdef CONFIG_ALPHA_JENSEN
494#  define RTC_PORT(x)	(0x170+(x))
495# else
496#  define RTC_PORT(x)	(0x70 + (x))
497# endif
498#endif
499#define RTC_ALWAYS_BCD	0
500
501/* Nothing to do */
502
503#define dma_cache_inv(_start,_size)		do { } while (0)
504#define dma_cache_wback(_start,_size)		do { } while (0)
505#define dma_cache_wback_inv(_start,_size)	do { } while (0)
506
507#endif /* __KERNEL__ */
508
509#endif /* __ALPHA_IO_H */
510