Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | #ifndef __ALPHA_APECS__H__ |
| 2 | #define __ALPHA_APECS__H__ |
| 3 | |
| 4 | #include <linux/types.h> |
| 5 | #include <asm/compiler.h> |
| 6 | |
| 7 | /* |
| 8 | * APECS is the internal name for the 2107x chipset which provides |
| 9 | * memory controller and PCI access for the 21064 chip based systems. |
| 10 | * |
| 11 | * This file is based on: |
| 12 | * |
| 13 | * DECchip 21071-AA and DECchip 21072-AA Core Logic Chipsets |
| 14 | * Data Sheet |
| 15 | * |
| 16 | * EC-N0648-72 |
| 17 | * |
| 18 | * |
| 19 | * david.rusling@reo.mts.dec.com Initial Version. |
| 20 | * |
| 21 | */ |
| 22 | |
| 23 | /* |
| 24 | An AVANTI *might* be an XL, and an XL has only 27 bits of ISA address |
| 25 | that get passed through the PCI<->ISA bridge chip. So we've gotta use |
| 26 | both windows to max out the physical memory we can DMA to. Sigh... |
| 27 | |
| 28 | If we try a window at 0 for 1GB as a work-around, we run into conflicts |
| 29 | with ISA/PCI bus memory which can't be relocated, like VGA aperture and |
| 30 | BIOS ROMs. So we must put the windows high enough to avoid these areas. |
| 31 | |
| 32 | We put window 1 at BUS 64Mb for 64Mb, mapping physical 0 to 64Mb-1, |
| 33 | and window 2 at BUS 1Gb for 1Gb, mapping physical 0 to 1Gb-1. |
| 34 | Yes, this does map 0 to 64Mb-1 twice, but only window 1 will actually |
| 35 | be used for that range (via virt_to_bus()). |
| 36 | |
| 37 | Note that we actually fudge the window 1 maximum as 48Mb instead of 64Mb, |
| 38 | to keep virt_to_bus() from returning an address in the first window, for |
| 39 | a data area that goes beyond the 64Mb first DMA window. Sigh... |
| 40 | The fudge factor MUST match with <asm/dma.h> MAX_DMA_ADDRESS, but |
| 41 | we can't just use that here, because of header file looping... :-( |
| 42 | |
| 43 | Window 1 will be used for all DMA from the ISA bus; yes, that does |
| 44 | limit what memory an ISA floppy or sound card or Ethernet can touch, but |
| 45 | it's also a known limitation on other platforms as well. We use the |
| 46 | same technique that is used on INTEL platforms with similar limitation: |
| 47 | set MAX_DMA_ADDRESS and clear some pages' DMAable flags during mem_init(). |
| 48 | We trust that any ISA bus device drivers will *always* ask for DMAable |
| 49 | memory explicitly via kmalloc()/get_free_pages() flags arguments. |
| 50 | |
| 51 | Note that most PCI bus devices' drivers do *not* explicitly ask for |
| 52 | DMAable memory; they count on being able to DMA to any memory they |
| 53 | get from kmalloc()/get_free_pages(). They will also use window 1 for |
| 54 | any physical memory accesses below 64Mb; the rest will be handled by |
| 55 | window 2, maxing out at 1Gb of memory. I trust this is enough... :-) |
| 56 | |
| 57 | We hope that the area before the first window is large enough so that |
| 58 | there will be no overlap at the top end (64Mb). We *must* locate the |
| 59 | PCI cards' memory just below window 1, so that there's still the |
| 60 | possibility of being able to access it via SPARSE space. This is |
| 61 | important for cards such as the Matrox Millennium, whose Xserver |
| 62 | wants to access memory-mapped registers in byte and short lengths. |
| 63 | |
| 64 | Note that the XL is treated differently from the AVANTI, even though |
| 65 | for most other things they are identical. It didn't seem reasonable to |
| 66 | make the AVANTI support pay for the limitations of the XL. It is true, |
| 67 | however, that an XL kernel will run on an AVANTI without problems. |
| 68 | |
| 69 | %%% All of this should be obviated by the ability to route |
| 70 | everything through the iommu. |
| 71 | */ |
| 72 | |
| 73 | /* |
| 74 | * 21071-DA Control and Status registers. |
| 75 | * These are used for PCI memory access. |
| 76 | */ |
| 77 | #define APECS_IOC_DCSR (IDENT_ADDR + 0x1A0000000UL) |
| 78 | #define APECS_IOC_PEAR (IDENT_ADDR + 0x1A0000020UL) |
| 79 | #define APECS_IOC_SEAR (IDENT_ADDR + 0x1A0000040UL) |
| 80 | #define APECS_IOC_DR1 (IDENT_ADDR + 0x1A0000060UL) |
| 81 | #define APECS_IOC_DR2 (IDENT_ADDR + 0x1A0000080UL) |
| 82 | #define APECS_IOC_DR3 (IDENT_ADDR + 0x1A00000A0UL) |
| 83 | |
| 84 | #define APECS_IOC_TB1R (IDENT_ADDR + 0x1A00000C0UL) |
| 85 | #define APECS_IOC_TB2R (IDENT_ADDR + 0x1A00000E0UL) |
| 86 | |
| 87 | #define APECS_IOC_PB1R (IDENT_ADDR + 0x1A0000100UL) |
| 88 | #define APECS_IOC_PB2R (IDENT_ADDR + 0x1A0000120UL) |
| 89 | |
| 90 | #define APECS_IOC_PM1R (IDENT_ADDR + 0x1A0000140UL) |
| 91 | #define APECS_IOC_PM2R (IDENT_ADDR + 0x1A0000160UL) |
| 92 | |
| 93 | #define APECS_IOC_HAXR0 (IDENT_ADDR + 0x1A0000180UL) |
| 94 | #define APECS_IOC_HAXR1 (IDENT_ADDR + 0x1A00001A0UL) |
| 95 | #define APECS_IOC_HAXR2 (IDENT_ADDR + 0x1A00001C0UL) |
| 96 | |
| 97 | #define APECS_IOC_PMLT (IDENT_ADDR + 0x1A00001E0UL) |
| 98 | |
| 99 | #define APECS_IOC_TLBTAG0 (IDENT_ADDR + 0x1A0000200UL) |
| 100 | #define APECS_IOC_TLBTAG1 (IDENT_ADDR + 0x1A0000220UL) |
| 101 | #define APECS_IOC_TLBTAG2 (IDENT_ADDR + 0x1A0000240UL) |
| 102 | #define APECS_IOC_TLBTAG3 (IDENT_ADDR + 0x1A0000260UL) |
| 103 | #define APECS_IOC_TLBTAG4 (IDENT_ADDR + 0x1A0000280UL) |
| 104 | #define APECS_IOC_TLBTAG5 (IDENT_ADDR + 0x1A00002A0UL) |
| 105 | #define APECS_IOC_TLBTAG6 (IDENT_ADDR + 0x1A00002C0UL) |
| 106 | #define APECS_IOC_TLBTAG7 (IDENT_ADDR + 0x1A00002E0UL) |
| 107 | |
| 108 | #define APECS_IOC_TLBDATA0 (IDENT_ADDR + 0x1A0000300UL) |
| 109 | #define APECS_IOC_TLBDATA1 (IDENT_ADDR + 0x1A0000320UL) |
| 110 | #define APECS_IOC_TLBDATA2 (IDENT_ADDR + 0x1A0000340UL) |
| 111 | #define APECS_IOC_TLBDATA3 (IDENT_ADDR + 0x1A0000360UL) |
| 112 | #define APECS_IOC_TLBDATA4 (IDENT_ADDR + 0x1A0000380UL) |
| 113 | #define APECS_IOC_TLBDATA5 (IDENT_ADDR + 0x1A00003A0UL) |
| 114 | #define APECS_IOC_TLBDATA6 (IDENT_ADDR + 0x1A00003C0UL) |
| 115 | #define APECS_IOC_TLBDATA7 (IDENT_ADDR + 0x1A00003E0UL) |
| 116 | |
| 117 | #define APECS_IOC_TBIA (IDENT_ADDR + 0x1A0000400UL) |
| 118 | |
| 119 | |
| 120 | /* |
| 121 | * 21071-CA Control and Status registers. |
| 122 | * These are used to program memory timing, |
| 123 | * configure memory and initialise the B-Cache. |
| 124 | */ |
| 125 | #define APECS_MEM_GCR (IDENT_ADDR + 0x180000000UL) |
| 126 | #define APECS_MEM_EDSR (IDENT_ADDR + 0x180000040UL) |
| 127 | #define APECS_MEM_TAR (IDENT_ADDR + 0x180000060UL) |
| 128 | #define APECS_MEM_ELAR (IDENT_ADDR + 0x180000080UL) |
| 129 | #define APECS_MEM_EHAR (IDENT_ADDR + 0x1800000a0UL) |
| 130 | #define APECS_MEM_SFT_RST (IDENT_ADDR + 0x1800000c0UL) |
| 131 | #define APECS_MEM_LDxLAR (IDENT_ADDR + 0x1800000e0UL) |
| 132 | #define APECS_MEM_LDxHAR (IDENT_ADDR + 0x180000100UL) |
| 133 | #define APECS_MEM_GTR (IDENT_ADDR + 0x180000200UL) |
| 134 | #define APECS_MEM_RTR (IDENT_ADDR + 0x180000220UL) |
| 135 | #define APECS_MEM_VFPR (IDENT_ADDR + 0x180000240UL) |
| 136 | #define APECS_MEM_PDLDR (IDENT_ADDR + 0x180000260UL) |
| 137 | #define APECS_MEM_PDhDR (IDENT_ADDR + 0x180000280UL) |
| 138 | |
| 139 | /* Bank x Base Address Register */ |
| 140 | #define APECS_MEM_B0BAR (IDENT_ADDR + 0x180000800UL) |
| 141 | #define APECS_MEM_B1BAR (IDENT_ADDR + 0x180000820UL) |
| 142 | #define APECS_MEM_B2BAR (IDENT_ADDR + 0x180000840UL) |
| 143 | #define APECS_MEM_B3BAR (IDENT_ADDR + 0x180000860UL) |
| 144 | #define APECS_MEM_B4BAR (IDENT_ADDR + 0x180000880UL) |
| 145 | #define APECS_MEM_B5BAR (IDENT_ADDR + 0x1800008A0UL) |
| 146 | #define APECS_MEM_B6BAR (IDENT_ADDR + 0x1800008C0UL) |
| 147 | #define APECS_MEM_B7BAR (IDENT_ADDR + 0x1800008E0UL) |
| 148 | #define APECS_MEM_B8BAR (IDENT_ADDR + 0x180000900UL) |
| 149 | |
| 150 | /* Bank x Configuration Register */ |
| 151 | #define APECS_MEM_B0BCR (IDENT_ADDR + 0x180000A00UL) |
| 152 | #define APECS_MEM_B1BCR (IDENT_ADDR + 0x180000A20UL) |
| 153 | #define APECS_MEM_B2BCR (IDENT_ADDR + 0x180000A40UL) |
| 154 | #define APECS_MEM_B3BCR (IDENT_ADDR + 0x180000A60UL) |
| 155 | #define APECS_MEM_B4BCR (IDENT_ADDR + 0x180000A80UL) |
| 156 | #define APECS_MEM_B5BCR (IDENT_ADDR + 0x180000AA0UL) |
| 157 | #define APECS_MEM_B6BCR (IDENT_ADDR + 0x180000AC0UL) |
| 158 | #define APECS_MEM_B7BCR (IDENT_ADDR + 0x180000AE0UL) |
| 159 | #define APECS_MEM_B8BCR (IDENT_ADDR + 0x180000B00UL) |
| 160 | |
| 161 | /* Bank x Timing Register A */ |
| 162 | #define APECS_MEM_B0TRA (IDENT_ADDR + 0x180000C00UL) |
| 163 | #define APECS_MEM_B1TRA (IDENT_ADDR + 0x180000C20UL) |
| 164 | #define APECS_MEM_B2TRA (IDENT_ADDR + 0x180000C40UL) |
| 165 | #define APECS_MEM_B3TRA (IDENT_ADDR + 0x180000C60UL) |
| 166 | #define APECS_MEM_B4TRA (IDENT_ADDR + 0x180000C80UL) |
| 167 | #define APECS_MEM_B5TRA (IDENT_ADDR + 0x180000CA0UL) |
| 168 | #define APECS_MEM_B6TRA (IDENT_ADDR + 0x180000CC0UL) |
| 169 | #define APECS_MEM_B7TRA (IDENT_ADDR + 0x180000CE0UL) |
| 170 | #define APECS_MEM_B8TRA (IDENT_ADDR + 0x180000D00UL) |
| 171 | |
| 172 | /* Bank x Timing Register B */ |
| 173 | #define APECS_MEM_B0TRB (IDENT_ADDR + 0x180000E00UL) |
| 174 | #define APECS_MEM_B1TRB (IDENT_ADDR + 0x180000E20UL) |
| 175 | #define APECS_MEM_B2TRB (IDENT_ADDR + 0x180000E40UL) |
| 176 | #define APECS_MEM_B3TRB (IDENT_ADDR + 0x180000E60UL) |
| 177 | #define APECS_MEM_B4TRB (IDENT_ADDR + 0x180000E80UL) |
| 178 | #define APECS_MEM_B5TRB (IDENT_ADDR + 0x180000EA0UL) |
| 179 | #define APECS_MEM_B6TRB (IDENT_ADDR + 0x180000EC0UL) |
| 180 | #define APECS_MEM_B7TRB (IDENT_ADDR + 0x180000EE0UL) |
| 181 | #define APECS_MEM_B8TRB (IDENT_ADDR + 0x180000F00UL) |
| 182 | |
| 183 | |
| 184 | /* |
| 185 | * Memory spaces: |
| 186 | */ |
| 187 | #define APECS_IACK_SC (IDENT_ADDR + 0x1b0000000UL) |
| 188 | #define APECS_CONF (IDENT_ADDR + 0x1e0000000UL) |
| 189 | #define APECS_IO (IDENT_ADDR + 0x1c0000000UL) |
| 190 | #define APECS_SPARSE_MEM (IDENT_ADDR + 0x200000000UL) |
| 191 | #define APECS_DENSE_MEM (IDENT_ADDR + 0x300000000UL) |
| 192 | |
| 193 | |
| 194 | /* |
| 195 | * Bit definitions for I/O Controller status register 0: |
| 196 | */ |
| 197 | #define APECS_IOC_STAT0_CMD 0xf |
| 198 | #define APECS_IOC_STAT0_ERR (1<<4) |
| 199 | #define APECS_IOC_STAT0_LOST (1<<5) |
| 200 | #define APECS_IOC_STAT0_THIT (1<<6) |
| 201 | #define APECS_IOC_STAT0_TREF (1<<7) |
| 202 | #define APECS_IOC_STAT0_CODE_SHIFT 8 |
| 203 | #define APECS_IOC_STAT0_CODE_MASK 0x7 |
| 204 | #define APECS_IOC_STAT0_P_NBR_SHIFT 13 |
| 205 | #define APECS_IOC_STAT0_P_NBR_MASK 0x7ffff |
| 206 | |
| 207 | #define APECS_HAE_ADDRESS APECS_IOC_HAXR1 |
| 208 | |
| 209 | |
| 210 | /* |
| 211 | * Data structure for handling APECS machine checks: |
| 212 | */ |
| 213 | |
| 214 | struct el_apecs_mikasa_sysdata_mcheck |
| 215 | { |
| 216 | unsigned long coma_gcr; |
| 217 | unsigned long coma_edsr; |
| 218 | unsigned long coma_ter; |
| 219 | unsigned long coma_elar; |
| 220 | unsigned long coma_ehar; |
| 221 | unsigned long coma_ldlr; |
| 222 | unsigned long coma_ldhr; |
| 223 | unsigned long coma_base0; |
| 224 | unsigned long coma_base1; |
| 225 | unsigned long coma_base2; |
| 226 | unsigned long coma_base3; |
| 227 | unsigned long coma_cnfg0; |
| 228 | unsigned long coma_cnfg1; |
| 229 | unsigned long coma_cnfg2; |
| 230 | unsigned long coma_cnfg3; |
| 231 | unsigned long epic_dcsr; |
| 232 | unsigned long epic_pear; |
| 233 | unsigned long epic_sear; |
| 234 | unsigned long epic_tbr1; |
| 235 | unsigned long epic_tbr2; |
| 236 | unsigned long epic_pbr1; |
| 237 | unsigned long epic_pbr2; |
| 238 | unsigned long epic_pmr1; |
| 239 | unsigned long epic_pmr2; |
| 240 | unsigned long epic_harx1; |
| 241 | unsigned long epic_harx2; |
| 242 | unsigned long epic_pmlt; |
| 243 | unsigned long epic_tag0; |
| 244 | unsigned long epic_tag1; |
| 245 | unsigned long epic_tag2; |
| 246 | unsigned long epic_tag3; |
| 247 | unsigned long epic_tag4; |
| 248 | unsigned long epic_tag5; |
| 249 | unsigned long epic_tag6; |
| 250 | unsigned long epic_tag7; |
| 251 | unsigned long epic_data0; |
| 252 | unsigned long epic_data1; |
| 253 | unsigned long epic_data2; |
| 254 | unsigned long epic_data3; |
| 255 | unsigned long epic_data4; |
| 256 | unsigned long epic_data5; |
| 257 | unsigned long epic_data6; |
| 258 | unsigned long epic_data7; |
| 259 | |
| 260 | unsigned long pceb_vid; |
| 261 | unsigned long pceb_did; |
| 262 | unsigned long pceb_revision; |
| 263 | unsigned long pceb_command; |
| 264 | unsigned long pceb_status; |
| 265 | unsigned long pceb_latency; |
| 266 | unsigned long pceb_control; |
| 267 | unsigned long pceb_arbcon; |
| 268 | unsigned long pceb_arbpri; |
| 269 | |
| 270 | unsigned long esc_id; |
| 271 | unsigned long esc_revision; |
| 272 | unsigned long esc_int0; |
| 273 | unsigned long esc_int1; |
| 274 | unsigned long esc_elcr0; |
| 275 | unsigned long esc_elcr1; |
| 276 | unsigned long esc_last_eisa; |
| 277 | unsigned long esc_nmi_stat; |
| 278 | |
| 279 | unsigned long pci_ir; |
| 280 | unsigned long pci_imr; |
| 281 | unsigned long svr_mgr; |
| 282 | }; |
| 283 | |
| 284 | /* This for the normal APECS machines. */ |
| 285 | struct el_apecs_sysdata_mcheck |
| 286 | { |
| 287 | unsigned long coma_gcr; |
| 288 | unsigned long coma_edsr; |
| 289 | unsigned long coma_ter; |
| 290 | unsigned long coma_elar; |
| 291 | unsigned long coma_ehar; |
| 292 | unsigned long coma_ldlr; |
| 293 | unsigned long coma_ldhr; |
| 294 | unsigned long coma_base0; |
| 295 | unsigned long coma_base1; |
| 296 | unsigned long coma_base2; |
| 297 | unsigned long coma_cnfg0; |
| 298 | unsigned long coma_cnfg1; |
| 299 | unsigned long coma_cnfg2; |
| 300 | unsigned long epic_dcsr; |
| 301 | unsigned long epic_pear; |
| 302 | unsigned long epic_sear; |
| 303 | unsigned long epic_tbr1; |
| 304 | unsigned long epic_tbr2; |
| 305 | unsigned long epic_pbr1; |
| 306 | unsigned long epic_pbr2; |
| 307 | unsigned long epic_pmr1; |
| 308 | unsigned long epic_pmr2; |
| 309 | unsigned long epic_harx1; |
| 310 | unsigned long epic_harx2; |
| 311 | unsigned long epic_pmlt; |
| 312 | unsigned long epic_tag0; |
| 313 | unsigned long epic_tag1; |
| 314 | unsigned long epic_tag2; |
| 315 | unsigned long epic_tag3; |
| 316 | unsigned long epic_tag4; |
| 317 | unsigned long epic_tag5; |
| 318 | unsigned long epic_tag6; |
| 319 | unsigned long epic_tag7; |
| 320 | unsigned long epic_data0; |
| 321 | unsigned long epic_data1; |
| 322 | unsigned long epic_data2; |
| 323 | unsigned long epic_data3; |
| 324 | unsigned long epic_data4; |
| 325 | unsigned long epic_data5; |
| 326 | unsigned long epic_data6; |
| 327 | unsigned long epic_data7; |
| 328 | }; |
| 329 | |
| 330 | struct el_apecs_procdata |
| 331 | { |
| 332 | unsigned long paltemp[32]; /* PAL TEMP REGS. */ |
| 333 | /* EV4-specific fields */ |
| 334 | unsigned long exc_addr; /* Address of excepting instruction. */ |
| 335 | unsigned long exc_sum; /* Summary of arithmetic traps. */ |
| 336 | unsigned long exc_mask; /* Exception mask (from exc_sum). */ |
| 337 | unsigned long iccsr; /* IBox hardware enables. */ |
| 338 | unsigned long pal_base; /* Base address for PALcode. */ |
| 339 | unsigned long hier; /* Hardware Interrupt Enable. */ |
| 340 | unsigned long hirr; /* Hardware Interrupt Request. */ |
| 341 | unsigned long csr; /* D-stream fault info. */ |
| 342 | unsigned long dc_stat; /* D-cache status (ECC/Parity Err). */ |
| 343 | unsigned long dc_addr; /* EV3 Phys Addr for ECC/DPERR. */ |
| 344 | unsigned long abox_ctl; /* ABox Control Register. */ |
| 345 | unsigned long biu_stat; /* BIU Status. */ |
| 346 | unsigned long biu_addr; /* BUI Address. */ |
| 347 | unsigned long biu_ctl; /* BIU Control. */ |
| 348 | unsigned long fill_syndrome;/* For correcting ECC errors. */ |
| 349 | unsigned long fill_addr; /* Cache block which was being read */ |
| 350 | unsigned long va; /* Effective VA of fault or miss. */ |
| 351 | unsigned long bc_tag; /* Backup Cache Tag Probe Results.*/ |
| 352 | }; |
| 353 | |
| 354 | |
| 355 | #ifdef __KERNEL__ |
| 356 | |
| 357 | #ifndef __EXTERN_INLINE |
| 358 | #define __EXTERN_INLINE extern inline |
| 359 | #define __IO_EXTERN_INLINE |
| 360 | #endif |
| 361 | |
| 362 | /* |
| 363 | * I/O functions: |
| 364 | * |
| 365 | * Unlike Jensen, the APECS machines have no concept of local |
| 366 | * I/O---everything goes over the PCI bus. |
| 367 | * |
| 368 | * There is plenty room for optimization here. In particular, |
| 369 | * the Alpha's insb/insw/extb/extw should be useful in moving |
| 370 | * data to/from the right byte-lanes. |
| 371 | */ |
| 372 | |
| 373 | #define vip volatile int __force * |
| 374 | #define vuip volatile unsigned int __force * |
| 375 | #define vulp volatile unsigned long __force * |
| 376 | |
| 377 | #define APECS_SET_HAE \ |
| 378 | do { \ |
| 379 | if (addr >= (1UL << 24)) { \ |
| 380 | unsigned long msb = addr & 0xf8000000; \ |
| 381 | addr -= msb; \ |
| 382 | set_hae(msb); \ |
| 383 | } \ |
| 384 | } while (0) |
| 385 | |
| 386 | __EXTERN_INLINE unsigned int apecs_ioread8(void __iomem *xaddr) |
| 387 | { |
| 388 | unsigned long addr = (unsigned long) xaddr; |
| 389 | unsigned long result, base_and_type; |
| 390 | |
| 391 | if (addr >= APECS_DENSE_MEM) { |
| 392 | addr -= APECS_DENSE_MEM; |
| 393 | APECS_SET_HAE; |
| 394 | base_and_type = APECS_SPARSE_MEM + 0x00; |
| 395 | } else { |
| 396 | addr -= APECS_IO; |
| 397 | base_and_type = APECS_IO + 0x00; |
| 398 | } |
| 399 | |
| 400 | result = *(vip) ((addr << 5) + base_and_type); |
| 401 | return __kernel_extbl(result, addr & 3); |
| 402 | } |
| 403 | |
| 404 | __EXTERN_INLINE void apecs_iowrite8(u8 b, void __iomem *xaddr) |
| 405 | { |
| 406 | unsigned long addr = (unsigned long) xaddr; |
| 407 | unsigned long w, base_and_type; |
| 408 | |
| 409 | if (addr >= APECS_DENSE_MEM) { |
| 410 | addr -= APECS_DENSE_MEM; |
| 411 | APECS_SET_HAE; |
| 412 | base_and_type = APECS_SPARSE_MEM + 0x00; |
| 413 | } else { |
| 414 | addr -= APECS_IO; |
| 415 | base_and_type = APECS_IO + 0x00; |
| 416 | } |
| 417 | |
| 418 | w = __kernel_insbl(b, addr & 3); |
| 419 | *(vuip) ((addr << 5) + base_and_type) = w; |
| 420 | } |
| 421 | |
| 422 | __EXTERN_INLINE unsigned int apecs_ioread16(void __iomem *xaddr) |
| 423 | { |
| 424 | unsigned long addr = (unsigned long) xaddr; |
| 425 | unsigned long result, base_and_type; |
| 426 | |
| 427 | if (addr >= APECS_DENSE_MEM) { |
| 428 | addr -= APECS_DENSE_MEM; |
| 429 | APECS_SET_HAE; |
| 430 | base_and_type = APECS_SPARSE_MEM + 0x08; |
| 431 | } else { |
| 432 | addr -= APECS_IO; |
| 433 | base_and_type = APECS_IO + 0x08; |
| 434 | } |
| 435 | |
| 436 | result = *(vip) ((addr << 5) + base_and_type); |
| 437 | return __kernel_extwl(result, addr & 3); |
| 438 | } |
| 439 | |
| 440 | __EXTERN_INLINE void apecs_iowrite16(u16 b, void __iomem *xaddr) |
| 441 | { |
| 442 | unsigned long addr = (unsigned long) xaddr; |
| 443 | unsigned long w, base_and_type; |
| 444 | |
| 445 | if (addr >= APECS_DENSE_MEM) { |
| 446 | addr -= APECS_DENSE_MEM; |
| 447 | APECS_SET_HAE; |
| 448 | base_and_type = APECS_SPARSE_MEM + 0x08; |
| 449 | } else { |
| 450 | addr -= APECS_IO; |
| 451 | base_and_type = APECS_IO + 0x08; |
| 452 | } |
| 453 | |
| 454 | w = __kernel_inswl(b, addr & 3); |
| 455 | *(vuip) ((addr << 5) + base_and_type) = w; |
| 456 | } |
| 457 | |
| 458 | __EXTERN_INLINE unsigned int apecs_ioread32(void __iomem *xaddr) |
| 459 | { |
| 460 | unsigned long addr = (unsigned long) xaddr; |
| 461 | if (addr < APECS_DENSE_MEM) |
| 462 | addr = ((addr - APECS_IO) << 5) + APECS_IO + 0x18; |
| 463 | return *(vuip)addr; |
| 464 | } |
| 465 | |
| 466 | __EXTERN_INLINE void apecs_iowrite32(u32 b, void __iomem *xaddr) |
| 467 | { |
| 468 | unsigned long addr = (unsigned long) xaddr; |
| 469 | if (addr < APECS_DENSE_MEM) |
| 470 | addr = ((addr - APECS_IO) << 5) + APECS_IO + 0x18; |
| 471 | *(vuip)addr = b; |
| 472 | } |
| 473 | |
| 474 | __EXTERN_INLINE void __iomem *apecs_ioportmap(unsigned long addr) |
| 475 | { |
| 476 | return (void __iomem *)(addr + APECS_IO); |
| 477 | } |
| 478 | |
| 479 | __EXTERN_INLINE void __iomem *apecs_ioremap(unsigned long addr, |
| 480 | unsigned long size) |
| 481 | { |
| 482 | return (void __iomem *)(addr + APECS_DENSE_MEM); |
| 483 | } |
| 484 | |
| 485 | __EXTERN_INLINE int apecs_is_ioaddr(unsigned long addr) |
| 486 | { |
| 487 | return addr >= IDENT_ADDR + 0x180000000UL; |
| 488 | } |
| 489 | |
| 490 | __EXTERN_INLINE int apecs_is_mmio(const volatile void __iomem *addr) |
| 491 | { |
| 492 | return (unsigned long)addr >= APECS_DENSE_MEM; |
| 493 | } |
| 494 | |
| 495 | #undef APECS_SET_HAE |
| 496 | |
| 497 | #undef vip |
| 498 | #undef vuip |
| 499 | #undef vulp |
| 500 | |
| 501 | #undef __IO_PREFIX |
| 502 | #define __IO_PREFIX apecs |
| 503 | #define apecs_trivial_io_bw 0 |
| 504 | #define apecs_trivial_io_lq 0 |
| 505 | #define apecs_trivial_rw_bw 2 |
| 506 | #define apecs_trivial_rw_lq 1 |
| 507 | #define apecs_trivial_iounmap 1 |
| 508 | #include <asm/io_trivial.h> |
| 509 | |
| 510 | #ifdef __IO_EXTERN_INLINE |
| 511 | #undef __EXTERN_INLINE |
| 512 | #undef __IO_EXTERN_INLINE |
| 513 | #endif |
| 514 | |
| 515 | #endif /* __KERNEL__ */ |
| 516 | |
| 517 | #endif /* __ALPHA_APECS__H__ */ |