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 extern inline unsigned int ___bus_inb(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 123 {
 124         long result;
 125 
 126         __set_hae(0);
 127         result = *(volatile int *) ((addr << 7) + EISA_IO + 0x00);
 128         result >>= (addr & 3) * 8;
 129         return 0xffUL & result;
 130 }
 131 
 132 extern void __bus_outb(unsigned char b, unsigned long addr);
 133 extern inline void ___bus_outb(unsigned char b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 134 {
 135         __set_hae(0);
 136         *(volatile unsigned int *) ((addr << 7) + EISA_IO + 0x00) = b * 0x01010101;
 137         mb();
 138 }
 139 
 140 /*
 141  * It seems gcc is not very good at optimizing away logical
 142  * operations that result in operations across inline functions.
 143  * Which is why this is a macro.
 144  */
 145 #define __is_local(addr) ( \
 146 /* keyboard */  (addr == 0x60 || addr == 0x64) || \
 147 /* RTC */       (addr == 0x170 || addr == 0x171) || \
 148 /* mb COM2 */   (addr >= 0x2f8 && addr <= 0x2ff) || \
 149 /* mb LPT1 */   (addr >= 0x3bc && addr <= 0x3be) || \
 150 /* mb COM2 */   (addr >= 0x3f8 && addr <= 0x3ff))
 151 
 152 extern inline unsigned int __inb(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 153 {
 154         if (__is_local(addr))
 155                 return __local_inb(addr);
 156         return __bus_inb(addr);
 157 }
 158 
 159 extern inline void __outb(unsigned char b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 160 {
 161         if (__is_local(addr))
 162                 __local_outb(b, addr);
 163         else
 164                 __bus_outb(b, addr);
 165 }
 166 
 167 extern inline unsigned int __inw(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 168 {
 169         long result;
 170 
 171         __set_hae(0);
 172         result = *(volatile int *) ((addr << 7) + EISA_IO + 0x20);
 173         result >>= (addr & 3) * 8;
 174         return 0xffffUL & result;
 175 }
 176 
 177 extern inline unsigned int __inl(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 178 {
 179         __set_hae(0);
 180         return *(volatile unsigned int *) ((addr << 7) + EISA_IO + 0x60);
 181 }
 182 
 183 extern inline void __outw(unsigned short b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 184 {
 185         __set_hae(0);
 186         *(volatile unsigned int *) ((addr << 7) + EISA_IO + 0x20) = b * 0x00010001;
 187         mb();
 188 }
 189 
 190 extern inline void __outl(unsigned int b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 191 {
 192         __set_hae(0);
 193         *(volatile unsigned int *) ((addr << 7) + EISA_IO + 0x60) = b;
 194         mb();
 195 }
 196 
 197 /*
 198  * Memory functions.
 199  */
 200 extern inline unsigned long __readb(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 201 {
 202         long result;
 203 
 204         __set_hae(addr);
 205         addr &= __HAE_MASK;
 206         result = *(volatile int *) ((addr << 7) + EISA_MEM + 0x00);
 207         result >>= (addr & 3) * 8;
 208         return 0xffUL & result;
 209 }
 210 
 211 extern inline unsigned long __readw(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 212 {
 213         long result;
 214 
 215         __set_hae(addr);
 216         addr &= __HAE_MASK;
 217         result = *(volatile int *) ((addr << 7) + EISA_MEM + 0x20);
 218         result >>= (addr & 3) * 8;
 219         return 0xffffUL & result;
 220 }
 221 
 222 extern inline unsigned long __readl(unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 223 {
 224         __set_hae(addr);
 225         addr &= __HAE_MASK;
 226         return *(volatile unsigned int *) ((addr << 7) + EISA_MEM + 0x60);
 227 }
 228 
 229 extern inline void __writeb(unsigned short b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 230 {
 231         __set_hae(addr);
 232         addr &= __HAE_MASK;
 233         *(volatile unsigned int *) ((addr << 7) + EISA_MEM + 0x00) = b * 0x01010101;
 234 }
 235 
 236 extern inline void __writew(unsigned short b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 237 {
 238         __set_hae(addr);
 239         addr &= __HAE_MASK;
 240         *(volatile unsigned int *) ((addr << 7) + EISA_MEM + 0x20) = b * 0x00010001;
 241 }
 242 
 243 extern inline void __writel(unsigned int b, unsigned long addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 244 {
 245         __set_hae(addr);
 246         addr &= __HAE_MASK;
 247         *(volatile unsigned int *) ((addr << 7) + EISA_MEM + 0x60) = b;
 248 }
 249 
 250 /*
 251  * The above have so much overhead that it probably doesn't make
 252  * sense to have them inlined (better icache behaviour).
 253  */
 254 extern unsigned int inb(unsigned long addr);
 255 extern unsigned int inw(unsigned long addr);
 256 extern unsigned int inl(unsigned long addr);
 257 
 258 extern void outb(unsigned char b, unsigned long addr);
 259 extern void outw(unsigned short b, unsigned long addr);
 260 extern void outl(unsigned int b, unsigned long addr);
 261 
 262 extern unsigned long readb(unsigned long addr);
 263 extern unsigned long readw(unsigned long addr);
 264 extern unsigned long readl(unsigned long addr);
 265 
 266 extern void writeb(unsigned char b, unsigned long addr);
 267 extern void writew(unsigned short b, unsigned long addr);
 268 extern void writel(unsigned int b, unsigned long addr);
 269 
 270 #define inb(port) \
 271 (__builtin_constant_p((port))?__inb(port):(inb)(port))
 272 
 273 #define outb(x, port) \
 274 (__builtin_constant_p((port))?__outb((x),(port)):(outb)((x),(port)))
 275 
 276 #define inb_p inb
 277 #define outb_p outb
 278 
 279 /*
 280  * The Alpha Jensen hardware for some rather strange reason puts
 281  * the RTC clock at 0x170 instead of 0x70. Probably due to some
 282  * misguided idea about using 0x70 for NMI stuff.
 283  *
 284  * These defines will override the defaults when doing RTC queries
 285  */
 286 #define RTC_PORT(x)     (0x170+(x))
 287 #define RTC_ADDR(x)     (x)
 288 #define RTC_ALWAYS_BCD  0
 289 
 290 #endif

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