root/include/asm-alpha/jensen.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. __set_hae
  2. __local_inb
  3. __local_outb
  4. __bus_inb
  5. __bus_outb
  6. __inb
  7. __outb
  8. __inw
  9. __inl
  10. __outw
  11. __outl
  12. __readb
  13. __readw
  14. __readl
  15. __writeb
  16. __writew
  17. __writel

   1 #ifndef __ALPHA_JENSEN_H
   2 #define __ALPHA_JENSEN_H
   3 
   4 /*
   5  * Defines for the AlphaPC EISA IO and memory address space.
   6  */
   7 
   8 /*
   9  * NOTE! The memory operations do not set any memory barriers, as it's
  10  * not needed for cases like a frame buffer that is essentially memory-like.
  11  * You need to do them by hand if the operations depend on ordering.
  12  *
  13  * Similarly, the port IO operations do a "mb" only after a write operation:
  14  * if an mb is needed before (as in the case of doing memory mapped IO
  15  * first, and then a port IO operation to the same device), it needs to be
  16  * done by hand.
  17  *
  18  * After the above has bitten me 100 times, I'll give up and just do the
  19  * mb all the time, but right now I'm hoping this will work out.  Avoiding
  20  * mb's may potentially be a noticeable speed improvement, but I can't
  21  * honestly say I've tested it.
  22  *
  23  * Handling interrupts that need to do mb's to synchronize to non-interrupts
  24  * is another fun race area.  Don't do it (because if you do, I'll have to
  25  * do *everything* with interrupts disabled, ugh).
  26  */
  27 
  28 /*
  29  * EISA Interrupt Acknowledge address
  30  */
  31 #define EISA_INTA               (IDENT_ADDR + 0x100000000UL)
  32 
  33 /*
  34  * FEPROM addresses
  35  */
  36 #define EISA_FEPROM0            (IDENT_ADDR + 0x180000000UL)
  37 #define EISA_FEPROM1            (IDENT_ADDR + 0x1A0000000UL)
  38 
  39 /*
  40  * VL82C106 base address
  41  */
  42 #define EISA_VL82C106           (IDENT_ADDR + 0x1C0000000UL)
  43 
  44 /*
  45  * EISA "Host Address Extension" address (bits 25-31 of the EISA address)
  46  */
  47 #define EISA_HAE                (IDENT_ADDR + 0x1D0000000UL)
  48 
  49 /*
  50  * "SYSCTL" register address
  51  */
  52 #define EISA_SYSCTL             (IDENT_ADDR + 0x1E0000000UL)
  53 
  54 /*
  55  * "spare" register address
  56  */
  57 #define EISA_SPARE              (IDENT_ADDR + 0x1F0000000UL)
  58 
  59 /*
  60  * EISA memory address offset
  61  */
  62 #define EISA_MEM                (IDENT_ADDR + 0x200000000UL)
  63 
  64 /*
  65  * EISA IO address offset
  66  */
  67 #define EISA_IO                 (IDENT_ADDR + 0x300000000UL)
  68 
  69 /*
  70  * Change virtual addresses to bus addresses and vv.
  71  *
  72  * NOTE! On the Jensen, the physical address is the same
  73  * as the bus address, but this is not necessarily true on
  74  * other alpha hardware.
  75  */
  76 #define virt_to_bus virt_to_phys
  77 #define bus_to_virt phys_to_virt
  78 
  79 #define HAE_ADDRESS     EISA_HAE
  80 
  81 /*
  82  * Handle the "host address register". This needs to be set
  83  * to the high 7 bits of the EISA address.  This is also needed
  84  * for EISA IO addresses, which are only 16 bits wide (the
  85  * hae needs to be set to 0).
  86  *
  87  * HAE isn't needed for the local IO operations, though.
  88  */
  89 #define __HAE_MASK 0x1ffffff
  90 extern inline void __set_hae(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
  91 {
  92         /* hae on the Jensen is bits 31:25 shifted right */
  93         addr >>= 25;
  94         if (addr != hae.cache)
  95                 set_hae(addr);
  96 }
  97 
  98 /*
  99  * IO functions
 100  *
 101  * The "local" functions are those that don't go out to the EISA bus,
 102  * but instead act on the VL82C106 chip directly.. This is mainly the
 103  * keyboard, RTC,  printer and first two serial lines..
 104  *
 105  * The local stuff makes for some complications, but it seems to be
 106  * gone in the PCI version. I hope I can get DEC suckered^H^H^H^H^H^H^H^H
 107  * convinced that I need one of the newer machines.
 108  */
 109 extern inline unsigned int __local_inb(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 110 {
 111         long result = *(volatile int *) ((addr << 9) + EISA_VL82C106);
 112         return 0xffUL & result;
 113 }
 114 
 115 extern inline void __local_outb(unsigned char b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 116 {
 117         *(volatile unsigned int *) ((addr << 9) + EISA_VL82C106) = b;
 118         mb();
 119 }
 120 
 121 extern unsigned int _bus_inb(unsigned long addr);
 122 
 123 extern inline unsigned int __bus_inb(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 124 {
 125         long result;
 126 
 127         __set_hae(0);
 128         result = *(volatile int *) ((addr << 7) + EISA_IO + 0x00);
 129         result >>= (addr & 3) * 8;
 130         return 0xffUL & result;
 131 }
 132 
 133 extern void _bus_outb(unsigned char b, unsigned long addr);
 134 
 135 extern inline void __bus_outb(unsigned char b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 136 {
 137         __set_hae(0);
 138         *(volatile unsigned int *) ((addr << 7) + EISA_IO + 0x00) = b * 0x01010101;
 139         mb();
 140 }
 141 
 142 /*
 143  * It seems gcc is not very good at optimizing away logical
 144  * operations that result in operations across inline functions.
 145  * Which is why this is a macro.
 146  */
 147 #define __is_local(addr) ( \
 148 /* keyboard */  (addr == 0x60 || addr == 0x64) || \
 149 /* RTC */       (addr == 0x170 || addr == 0x171) || \
 150 /* mb COM2 */   (addr >= 0x2f8 && addr <= 0x2ff) || \
 151 /* mb LPT1 */   (addr >= 0x3bc && addr <= 0x3be) || \
 152 /* mb COM2 */   (addr >= 0x3f8 && addr <= 0x3ff))
 153 
 154 extern inline unsigned int __inb(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 155 {
 156         if (__is_local(addr))
 157                 return __local_inb(addr);
 158         return _bus_inb(addr);
 159 }
 160 
 161 extern inline void __outb(unsigned char b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 162 {
 163         if (__is_local(addr))
 164                 __local_outb(b, addr);
 165         else
 166                 _bus_outb(b, addr);
 167 }
 168 
 169 extern inline unsigned int __inw(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 170 {
 171         long result;
 172 
 173         __set_hae(0);
 174         result = *(volatile int *) ((addr << 7) + EISA_IO + 0x20);
 175         result >>= (addr & 3) * 8;
 176         return 0xffffUL & result;
 177 }
 178 
 179 extern inline unsigned int __inl(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 180 {
 181         __set_hae(0);
 182         return *(volatile unsigned int *) ((addr << 7) + EISA_IO + 0x60);
 183 }
 184 
 185 extern inline void __outw(unsigned short b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 186 {
 187         __set_hae(0);
 188         *(volatile unsigned int *) ((addr << 7) + EISA_IO + 0x20) = b * 0x00010001;
 189         mb();
 190 }
 191 
 192 extern inline void __outl(unsigned int b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 193 {
 194         __set_hae(0);
 195         *(volatile unsigned int *) ((addr << 7) + EISA_IO + 0x60) = b;
 196         mb();
 197 }
 198 
 199 /*
 200  * Memory functions.
 201  */
 202 extern inline unsigned long __readb(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 203 {
 204         long result;
 205 
 206         __set_hae(addr);
 207         addr &= __HAE_MASK;
 208         result = *(volatile int *) ((addr << 7) + EISA_MEM + 0x00);
 209         result >>= (addr & 3) * 8;
 210         return 0xffUL & result;
 211 }
 212 
 213 extern inline unsigned long __readw(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 214 {
 215         long result;
 216 
 217         __set_hae(addr);
 218         addr &= __HAE_MASK;
 219         result = *(volatile int *) ((addr << 7) + EISA_MEM + 0x20);
 220         result >>= (addr & 3) * 8;
 221         return 0xffffUL & result;
 222 }
 223 
 224 extern inline unsigned long __readl(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 225 {
 226         __set_hae(addr);
 227         addr &= __HAE_MASK;
 228         return *(volatile unsigned int *) ((addr << 7) + EISA_MEM + 0x60);
 229 }
 230 
 231 extern inline void __writeb(unsigned short b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 232 {
 233         __set_hae(addr);
 234         addr &= __HAE_MASK;
 235         *(volatile unsigned int *) ((addr << 7) + EISA_MEM + 0x00) = b * 0x01010101;
 236 }
 237 
 238 extern inline void __writew(unsigned short b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 239 {
 240         __set_hae(addr);
 241         addr &= __HAE_MASK;
 242         *(volatile unsigned int *) ((addr << 7) + EISA_MEM + 0x20) = b * 0x00010001;
 243 }
 244 
 245 extern inline void __writel(unsigned int b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 246 {
 247         __set_hae(addr);
 248         addr &= __HAE_MASK;
 249         *(volatile unsigned int *) ((addr << 7) + EISA_MEM + 0x60) = b;
 250 }
 251 
 252 /*
 253  * The above have so much overhead that it probably doesn't make
 254  * sense to have them inlined (better icache behaviour).
 255  */
 256 #define inb(port) \
 257 (__builtin_constant_p((port))?__inb(port):_inb(port))
 258 
 259 #define outb(x, port) \
 260 (__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port)))
 261 
 262 /*
 263  * The Alpha Jensen hardware for some rather strange reason puts
 264  * the RTC clock at 0x170 instead of 0x70. Probably due to some
 265  * misguided idea about using 0x70 for NMI stuff.
 266  *
 267  * These defines will override the defaults when doing RTC queries
 268  */
 269 #define RTC_PORT(x)     (0x170+(x))
 270 #define RTC_ADDR(x)     (x)
 271 #define RTC_ALWAYS_BCD  0
 272 
 273 #endif

/* [previous][next][first][last][top][bottom][index][help] */