Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:53

0001 /*
0002  * io.h
0003  *
0004  *      This file contains inline implementation of function to
0005  *          deal with IO.
0006  *
0007  * It is a stripped down version of linux ppc file...
0008  *
0009  * Copyright (C) 1999  Eric Valette (valette@crf.canon.fr)
0010  *                     Canon Centre Recherche France.
0011  *
0012  *  The license and distribution terms for this file may be
0013  *  found in the file LICENSE in this distribution or at
0014  *  http://www.rtems.org/license/LICENSE.
0015  */
0016 #ifndef _LIBCPU_IO_H
0017 #define _LIBCPU_IO_H
0018 
0019 
0020 #define PREP_ISA_IO_BASE    0x80000000
0021 #define PREP_ISA_MEM_BASE   0xc0000000
0022 #define PREP_PCI_DRAM_OFFSET    0x80000000
0023 
0024 #define CHRP_ISA_IO_BASE    0xfe000000
0025 #define CHRP_ISA_MEM_BASE   0xfd000000
0026 #define CHRP_PCI_DRAM_OFFSET    0x00000000
0027 
0028 /* _IO_BASE, _ISA_MEM_BASE, PCI_DRAM_OFFSET are now defined by bsp.h */
0029 
0030 #ifndef ASM
0031 
0032 #include <bsp.h>        /* for _IO_BASE & friends */
0033 #include <stdint.h>
0034 
0035 /* NOTE: The use of these macros is DISCOURAGED.
0036  *       you should consider e.g. using in_xxx / out_xxx
0037  *       with a device specific base address that is
0038  *       defined by the BSP. This makes drivers easier
0039  *       to port.
0040  */
0041 #define inb(port)       in_8((uint8_t *)((port)+_IO_BASE))
0042 #define outb(val, port)     out_8((uint8_t *)((port)+_IO_BASE), (val))
0043 #define inw(port)       in_le16((uint16_t *)((port)+_IO_BASE))
0044 #define outw(val, port)     out_le16((uint16_t *)((port)+_IO_BASE), (val))
0045 #define inl(port)       in_le32((uint32_t *)((port)+_IO_BASE))
0046 #define outl(val, port)     out_le32((uint32_t *)((port)+_IO_BASE), (val))
0047 
0048 /*
0049  * Enforce In-order Execution of I/O:
0050  * Acts as a barrier to ensure all previous I/O accesses have
0051  * completed before any further ones are issued.
0052  */
0053 static inline void io_eieio(void)
0054 {
0055     __asm__ __volatile__ ("eieio");
0056 }
0057 
0058 
0059 /* Enforce in-order execution of data I/O.
0060  * No distinction between read/write on PPC; use eieio for all three.
0061  */
0062 #define iobarrier_rw() io_eieio()
0063 #define iobarrier_r()  io_eieio()
0064 #define iobarrier_w()  io_eieio()
0065 
0066 /*
0067  * 8, 16 and 32 bit, big and little endian I/O operations, with barrier.
0068  */
0069 static inline uint8_t in_8(const volatile uint8_t *addr)
0070 {
0071     uint8_t ret;
0072 
0073     __asm__ __volatile__("lbz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));
0074     return ret;
0075 }
0076 
0077 static inline void out_8(volatile uint8_t *addr, uint8_t val)
0078 {
0079     __asm__ __volatile__("stb%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
0080 }
0081 
0082 static inline uint16_t in_le16(const volatile uint16_t *addr)
0083 {
0084     uint16_t ret;
0085 
0086     __asm__ __volatile__("lhbrx %0,0,%1; eieio" : "=r" (ret) :
0087                   "r" (addr), "m" (*addr));
0088     return ret;
0089 }
0090 
0091 static inline uint16_t in_be16(const volatile uint16_t *addr)
0092 {
0093     uint16_t ret;
0094 
0095     __asm__ __volatile__("lhz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));
0096     return ret;
0097 }
0098 
0099 static inline void out_le16(volatile uint16_t *addr, uint16_t val)
0100 {
0101     __asm__ __volatile__("sthbrx %1,0,%2; eieio" : "=m" (*addr) :
0102                   "r" (val), "r" (addr));
0103 }
0104 
0105 static inline void out_be16(volatile uint16_t *addr, uint16_t val)
0106 {
0107     __asm__ __volatile__("sth%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
0108 }
0109 
0110 #ifndef in_le32
0111 static inline uint32_t in_le32(const volatile uint32_t *addr)
0112 {
0113     uint32_t ret;
0114 
0115     __asm__ __volatile__("lwbrx %0,0,%1; eieio" : "=r" (ret) :
0116                  "r" (addr), "m" (*addr));
0117     return ret;
0118 }
0119 #endif
0120 
0121 #ifndef in_be32
0122 static inline uint32_t in_be32(const volatile uint32_t *addr)
0123 {
0124     uint32_t ret;
0125 
0126     __asm__ __volatile__("lwz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));
0127     return ret;
0128 }
0129 #endif
0130 
0131 #ifndef out_le32
0132 static inline void out_le32(volatile uint32_t *addr, uint32_t val)
0133 {
0134     __asm__ __volatile__("stwbrx %1,0,%2; eieio" : "=m" (*addr) :
0135                  "r" (val), "r" (addr));
0136 }
0137 #endif
0138 
0139 #ifndef out_be32
0140 static inline void out_be32(volatile uint32_t *addr, uint32_t val)
0141 {
0142     __asm__ __volatile__("stw%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
0143 }
0144 #endif
0145 
0146 #endif /* ASM */
0147 #endif /* _LIBCPU_IO_H */