cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

jensen.h (8603B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef __ALPHA_JENSEN_H
      3#define __ALPHA_JENSEN_H
      4
      5#include <asm/compiler.h>
      6
      7/*
      8 * Defines for the AlphaPC EISA IO and memory address space.
      9 */
     10
     11/*
     12 * NOTE! The memory operations do not set any memory barriers, as it's
     13 * not needed for cases like a frame buffer that is essentially memory-like.
     14 * You need to do them by hand if the operations depend on ordering.
     15 *
     16 * Similarly, the port IO operations do a "mb" only after a write operation:
     17 * if an mb is needed before (as in the case of doing memory mapped IO
     18 * first, and then a port IO operation to the same device), it needs to be
     19 * done by hand.
     20 *
     21 * After the above has bitten me 100 times, I'll give up and just do the
     22 * mb all the time, but right now I'm hoping this will work out.  Avoiding
     23 * mb's may potentially be a noticeable speed improvement, but I can't
     24 * honestly say I've tested it.
     25 *
     26 * Handling interrupts that need to do mb's to synchronize to non-interrupts
     27 * is another fun race area.  Don't do it (because if you do, I'll have to
     28 * do *everything* with interrupts disabled, ugh).
     29 */
     30
     31/*
     32 * EISA Interrupt Acknowledge address
     33 */
     34#define EISA_INTA		(IDENT_ADDR + 0x100000000UL)
     35
     36/*
     37 * FEPROM addresses
     38 */
     39#define EISA_FEPROM0		(IDENT_ADDR + 0x180000000UL)
     40#define EISA_FEPROM1		(IDENT_ADDR + 0x1A0000000UL)
     41
     42/*
     43 * VL82C106 base address
     44 */
     45#define EISA_VL82C106		(IDENT_ADDR + 0x1C0000000UL)
     46
     47/*
     48 * EISA "Host Address Extension" address (bits 25-31 of the EISA address)
     49 */
     50#define EISA_HAE		(IDENT_ADDR + 0x1D0000000UL)
     51
     52/*
     53 * "SYSCTL" register address
     54 */
     55#define EISA_SYSCTL		(IDENT_ADDR + 0x1E0000000UL)
     56
     57/*
     58 * "spare" register address
     59 */
     60#define EISA_SPARE		(IDENT_ADDR + 0x1F0000000UL)
     61
     62/*
     63 * EISA memory address offset
     64 */
     65#define EISA_MEM		(IDENT_ADDR + 0x200000000UL)
     66
     67/*
     68 * EISA IO address offset
     69 */
     70#define EISA_IO			(IDENT_ADDR + 0x300000000UL)
     71
     72
     73#ifdef __KERNEL__
     74
     75#ifndef __EXTERN_INLINE
     76#define __EXTERN_INLINE extern inline
     77#define __IO_EXTERN_INLINE
     78#endif
     79
     80/*
     81 * Handle the "host address register". This needs to be set
     82 * to the high 7 bits of the EISA address.  This is also needed
     83 * for EISA IO addresses, which are only 16 bits wide (the
     84 * hae needs to be set to 0).
     85 *
     86 * HAE isn't needed for the local IO operations, though.
     87 */
     88
     89#define JENSEN_HAE_ADDRESS	EISA_HAE
     90#define JENSEN_HAE_MASK		0x1ffffff
     91
     92__EXTERN_INLINE void jensen_set_hae(unsigned long addr)
     93{
     94	/* hae on the Jensen is bits 31:25 shifted right */
     95	addr >>= 25;
     96	if (addr != alpha_mv.hae_cache)
     97		set_hae(addr);
     98}
     99
    100#define vuip	volatile unsigned int *
    101
    102/*
    103 * IO functions
    104 *
    105 * The "local" functions are those that don't go out to the EISA bus,
    106 * but instead act on the VL82C106 chip directly.. This is mainly the
    107 * keyboard, RTC,  printer and first two serial lines..
    108 *
    109 * The local stuff makes for some complications, but it seems to be
    110 * gone in the PCI version. I hope I can get DEC suckered^H^H^H^H^H^H^H^H
    111 * convinced that I need one of the newer machines.
    112 */
    113
    114__EXTERN_INLINE unsigned int jensen_local_inb(unsigned long addr)
    115{
    116	return 0xff & *(vuip)((addr << 9) + EISA_VL82C106);
    117}
    118
    119__EXTERN_INLINE void jensen_local_outb(u8 b, unsigned long addr)
    120{
    121	*(vuip)((addr << 9) + EISA_VL82C106) = b;
    122	mb();
    123}
    124
    125__EXTERN_INLINE unsigned int jensen_bus_inb(unsigned long addr)
    126{
    127	long result;
    128
    129	jensen_set_hae(0);
    130	result = *(volatile int *)((addr << 7) + EISA_IO + 0x00);
    131	return __kernel_extbl(result, addr & 3);
    132}
    133
    134__EXTERN_INLINE void jensen_bus_outb(u8 b, unsigned long addr)
    135{
    136	jensen_set_hae(0);
    137	*(vuip)((addr << 7) + EISA_IO + 0x00) = b * 0x01010101;
    138	mb();
    139}
    140
    141/*
    142 * It seems gcc is not very good at optimizing away logical
    143 * operations that result in operations across inline functions.
    144 * Which is why this is a macro.
    145 */
    146
    147#define jensen_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 u8 jensen_inb(unsigned long addr)
    155{
    156	if (jensen_is_local(addr))
    157		return jensen_local_inb(addr);
    158	else
    159		return jensen_bus_inb(addr);
    160}
    161
    162__EXTERN_INLINE void jensen_outb(u8 b, unsigned long addr)
    163{
    164	if (jensen_is_local(addr))
    165		jensen_local_outb(b, addr);
    166	else
    167		jensen_bus_outb(b, addr);
    168}
    169
    170__EXTERN_INLINE u16 jensen_inw(unsigned long addr)
    171{
    172	long result;
    173
    174	jensen_set_hae(0);
    175	result = *(volatile int *) ((addr << 7) + EISA_IO + 0x20);
    176	result >>= (addr & 3) * 8;
    177	return 0xffffUL & result;
    178}
    179
    180__EXTERN_INLINE u32 jensen_inl(unsigned long addr)
    181{
    182	jensen_set_hae(0);
    183	return *(vuip) ((addr << 7) + EISA_IO + 0x60);
    184}
    185
    186__EXTERN_INLINE void jensen_outw(u16 b, unsigned long addr)
    187{
    188	jensen_set_hae(0);
    189	*(vuip) ((addr << 7) + EISA_IO + 0x20) = b * 0x00010001;
    190	mb();
    191}
    192
    193__EXTERN_INLINE void jensen_outl(u32 b, unsigned long addr)
    194{
    195	jensen_set_hae(0);
    196	*(vuip) ((addr << 7) + EISA_IO + 0x60) = b;
    197	mb();
    198}
    199
    200/*
    201 * Memory functions.
    202 */
    203
    204__EXTERN_INLINE u8 jensen_readb(const volatile void __iomem *xaddr)
    205{
    206	unsigned long addr = (unsigned long) xaddr;
    207	long result;
    208
    209	jensen_set_hae(addr);
    210	addr &= JENSEN_HAE_MASK;
    211	result = *(volatile int *) ((addr << 7) + EISA_MEM + 0x00);
    212	result >>= (addr & 3) * 8;
    213	return 0xffUL & result;
    214}
    215
    216__EXTERN_INLINE u16 jensen_readw(const volatile void __iomem *xaddr)
    217{
    218	unsigned long addr = (unsigned long) xaddr;
    219	long result;
    220
    221	jensen_set_hae(addr);
    222	addr &= JENSEN_HAE_MASK;
    223	result = *(volatile int *) ((addr << 7) + EISA_MEM + 0x20);
    224	result >>= (addr & 3) * 8;
    225	return 0xffffUL & result;
    226}
    227
    228__EXTERN_INLINE u32 jensen_readl(const volatile void __iomem *xaddr)
    229{
    230	unsigned long addr = (unsigned long) xaddr;
    231	jensen_set_hae(addr);
    232	addr &= JENSEN_HAE_MASK;
    233	return *(vuip) ((addr << 7) + EISA_MEM + 0x60);
    234}
    235
    236__EXTERN_INLINE u64 jensen_readq(const volatile void __iomem *xaddr)
    237{
    238	unsigned long addr = (unsigned long) xaddr;
    239	unsigned long r0, r1;
    240
    241	jensen_set_hae(addr);
    242	addr &= JENSEN_HAE_MASK;
    243	addr = (addr << 7) + EISA_MEM + 0x60;
    244	r0 = *(vuip) (addr);
    245	r1 = *(vuip) (addr + (4 << 7));
    246	return r1 << 32 | r0;
    247}
    248
    249__EXTERN_INLINE void jensen_writeb(u8 b, volatile void __iomem *xaddr)
    250{
    251	unsigned long addr = (unsigned long) xaddr;
    252	jensen_set_hae(addr);
    253	addr &= JENSEN_HAE_MASK;
    254	*(vuip) ((addr << 7) + EISA_MEM + 0x00) = b * 0x01010101;
    255}
    256
    257__EXTERN_INLINE void jensen_writew(u16 b, volatile void __iomem *xaddr)
    258{
    259	unsigned long addr = (unsigned long) xaddr;
    260	jensen_set_hae(addr);
    261	addr &= JENSEN_HAE_MASK;
    262	*(vuip) ((addr << 7) + EISA_MEM + 0x20) = b * 0x00010001;
    263}
    264
    265__EXTERN_INLINE void jensen_writel(u32 b, volatile void __iomem *xaddr)
    266{
    267	unsigned long addr = (unsigned long) xaddr;
    268	jensen_set_hae(addr);
    269	addr &= JENSEN_HAE_MASK;
    270	*(vuip) ((addr << 7) + EISA_MEM + 0x60) = b;
    271}
    272
    273__EXTERN_INLINE void jensen_writeq(u64 b, volatile void __iomem *xaddr)
    274{
    275	unsigned long addr = (unsigned long) xaddr;
    276	jensen_set_hae(addr);
    277	addr &= JENSEN_HAE_MASK;
    278	addr = (addr << 7) + EISA_MEM + 0x60;
    279	*(vuip) (addr) = b;
    280	*(vuip) (addr + (4 << 7)) = b >> 32;
    281}
    282
    283__EXTERN_INLINE void __iomem *jensen_ioportmap(unsigned long addr)
    284{
    285	return (void __iomem *)addr;
    286}
    287
    288__EXTERN_INLINE void __iomem *jensen_ioremap(unsigned long addr,
    289					     unsigned long size)
    290{
    291	return (void __iomem *)(addr + 0x100000000ul);
    292}
    293
    294__EXTERN_INLINE int jensen_is_ioaddr(unsigned long addr)
    295{
    296	return (long)addr >= 0;
    297}
    298
    299__EXTERN_INLINE int jensen_is_mmio(const volatile void __iomem *addr)
    300{
    301	return (unsigned long)addr >= 0x100000000ul;
    302}
    303
    304/* New-style ioread interface.  All the routines are so ugly for Jensen
    305   that it doesn't make sense to merge them.  */
    306
    307#define IOPORT(OS, NS)							\
    308__EXTERN_INLINE unsigned int jensen_ioread##NS(const void __iomem *xaddr)	\
    309{									\
    310	if (jensen_is_mmio(xaddr))					\
    311		return jensen_read##OS(xaddr - 0x100000000ul);		\
    312	else								\
    313		return jensen_in##OS((unsigned long)xaddr);		\
    314}									\
    315__EXTERN_INLINE void jensen_iowrite##NS(u##NS b, void __iomem *xaddr)	\
    316{									\
    317	if (jensen_is_mmio(xaddr))					\
    318		jensen_write##OS(b, xaddr - 0x100000000ul);		\
    319	else								\
    320		jensen_out##OS(b, (unsigned long)xaddr);		\
    321}
    322
    323IOPORT(b, 8)
    324IOPORT(w, 16)
    325IOPORT(l, 32)
    326
    327#undef IOPORT
    328
    329#undef vuip
    330
    331#undef __IO_PREFIX
    332#define __IO_PREFIX		jensen
    333#define jensen_trivial_rw_bw	0
    334#define jensen_trivial_rw_lq	0
    335#define jensen_trivial_io_bw	0
    336#define jensen_trivial_io_lq	0
    337#define jensen_trivial_iounmap	1
    338#include <asm/io_trivial.h>
    339
    340#ifdef __IO_EXTERN_INLINE
    341#undef __EXTERN_INLINE
    342#undef __IO_EXTERN_INLINE
    343#endif
    344
    345#endif /* __KERNEL__ */
    346
    347#endif /* __ALPHA_JENSEN_H */