Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* $Id: obio.h,v 1.4 1998/03/09 14:04:55 jj Exp $ |
| 2 | * obio.h: Some useful locations in 0xFXXXXXXXX PA obio space on sun4d. |
| 3 | * |
| 4 | * Copyright (C) 1997 Jakub Jelinek <jj@sunsite.mff.cuni.cz> |
| 5 | */ |
| 6 | |
| 7 | #ifndef _SPARC_OBIO_H |
| 8 | #define _SPARC_OBIO_H |
| 9 | |
| 10 | #include <asm/asi.h> |
| 11 | |
| 12 | /* This weird monster likes to use the very upper parts of |
| 13 | 36bit PA for these things :) */ |
| 14 | |
| 15 | /* CSR space (for each XDBUS) |
| 16 | * ------------------------------------------------------------------------ |
| 17 | * | 0xFE | DEVID | | XDBUS ID | | |
| 18 | * ------------------------------------------------------------------------ |
| 19 | * 35 28 27 20 19 10 9 8 7 0 |
| 20 | */ |
| 21 | |
| 22 | #define CSR_BASE_ADDR 0xe0000000 |
| 23 | #define CSR_CPU_SHIFT (32 - 4 - 5) |
| 24 | #define CSR_XDBUS_SHIFT 8 |
| 25 | |
| 26 | #define CSR_BASE(cpu) (((CSR_BASE_ADDR >> CSR_CPU_SHIFT) + cpu) << CSR_CPU_SHIFT) |
| 27 | |
| 28 | /* ECSR space (not for each XDBUS) |
| 29 | * ------------------------------------------------------------------------ |
| 30 | * | 0xF | DEVID[7:1] | | |
| 31 | * ------------------------------------------------------------------------ |
| 32 | * 35 32 31 25 24 0 |
| 33 | */ |
| 34 | |
| 35 | #define ECSR_BASE_ADDR 0x00000000 |
| 36 | #define ECSR_CPU_SHIFT (32 - 5) |
| 37 | #define ECSR_DEV_SHIFT (32 - 8) |
| 38 | |
| 39 | #define ECSR_BASE(cpu) ((cpu) << ECSR_CPU_SHIFT) |
| 40 | #define ECSR_DEV_BASE(devid) ((devid) << ECSR_DEV_SHIFT) |
| 41 | |
| 42 | /* Bus Watcher */ |
| 43 | #define BW_LOCAL_BASE 0xfff00000 |
| 44 | |
| 45 | #define BW_CID 0x00000000 |
| 46 | #define BW_DBUS_CTRL 0x00000008 |
| 47 | #define BW_DBUS_DATA 0x00000010 |
| 48 | #define BW_CTRL 0x00001000 |
| 49 | #define BW_INTR_TABLE 0x00001040 |
| 50 | #define BW_INTR_TABLE_CLEAR 0x00001080 |
| 51 | #define BW_PRESCALER 0x000010c0 |
| 52 | #define BW_PTIMER_LIMIT 0x00002000 |
| 53 | #define BW_PTIMER_COUNTER2 0x00002004 |
| 54 | #define BW_PTIMER_NDLIMIT 0x00002008 |
| 55 | #define BW_PTIMER_CTRL 0x0000200c |
| 56 | #define BW_PTIMER_COUNTER 0x00002010 |
| 57 | #define BW_TIMER_LIMIT 0x00003000 |
| 58 | #define BW_TIMER_COUNTER2 0x00003004 |
| 59 | #define BW_TIMER_NDLIMIT 0x00003008 |
| 60 | #define BW_TIMER_CTRL 0x0000300c |
| 61 | #define BW_TIMER_COUNTER 0x00003010 |
| 62 | |
| 63 | /* BW Control */ |
| 64 | #define BW_CTRL_USER_TIMER 0x00000004 /* Is User Timer Free run enabled */ |
| 65 | |
| 66 | /* Boot Bus */ |
| 67 | #define BB_LOCAL_BASE 0xf0000000 |
| 68 | |
| 69 | #define BB_STAT1 0x00100000 |
| 70 | #define BB_STAT2 0x00120000 |
| 71 | #define BB_STAT3 0x00140000 |
| 72 | #define BB_LEDS 0x002e0000 |
| 73 | |
| 74 | /* Bits in BB_STAT2 */ |
| 75 | #define BB_STAT2_AC_INTR 0x04 /* Aiee! 5ms and power is gone... */ |
| 76 | #define BB_STAT2_TMP_INTR 0x10 /* My Penguins are burning. Are you able to smell it? */ |
| 77 | #define BB_STAT2_FAN_INTR 0x20 /* My fan refuses to work */ |
| 78 | #define BB_STAT2_PWR_INTR 0x40 /* On SC2000, one of the two ACs died. Ok, we go on... */ |
| 79 | #define BB_STAT2_MASK (BB_STAT2_AC_INTR|BB_STAT2_TMP_INTR|BB_STAT2_FAN_INTR|BB_STAT2_PWR_INTR) |
| 80 | |
| 81 | /* Cache Controller */ |
| 82 | #define CC_BASE 0x1F00000 |
| 83 | #define CC_DATSTREAM 0x1F00000 /* Data stream register */ |
| 84 | #define CC_DATSIZE 0x1F0003F /* Size */ |
| 85 | #define CC_SRCSTREAM 0x1F00100 /* Source stream register */ |
| 86 | #define CC_DESSTREAM 0x1F00200 /* Destination stream register */ |
| 87 | #define CC_RMCOUNT 0x1F00300 /* Count of references and misses */ |
| 88 | #define CC_IPEN 0x1F00406 /* Pending Interrupts */ |
| 89 | #define CC_IMSK 0x1F00506 /* Interrupt Mask */ |
| 90 | #define CC_ICLR 0x1F00606 /* Clear pending Interrupts */ |
| 91 | #define CC_IGEN 0x1F00704 /* Generate Interrupt register */ |
| 92 | #define CC_STEST 0x1F00804 /* Internal self-test */ |
| 93 | #define CC_CREG 0x1F00A04 /* Control register */ |
| 94 | #define CC_SREG 0x1F00B00 /* Status register */ |
| 95 | #define CC_RREG 0x1F00C04 /* Reset register */ |
| 96 | #define CC_EREG 0x1F00E00 /* Error code register */ |
| 97 | #define CC_CID 0x1F00F04 /* Component ID */ |
| 98 | |
| 99 | #ifndef __ASSEMBLY__ |
| 100 | |
| 101 | extern __inline__ int bw_get_intr_mask(int sbus_level) |
| 102 | { |
| 103 | int mask; |
| 104 | |
| 105 | __asm__ __volatile__ ("lduha [%1] %2, %0" : |
| 106 | "=r" (mask) : |
| 107 | "r" (BW_LOCAL_BASE + BW_INTR_TABLE + (sbus_level << 3)), |
| 108 | "i" (ASI_M_CTL)); |
| 109 | return mask; |
| 110 | } |
| 111 | |
| 112 | extern __inline__ void bw_clear_intr_mask(int sbus_level, int mask) |
| 113 | { |
| 114 | __asm__ __volatile__ ("stha %0, [%1] %2" : : |
| 115 | "r" (mask), |
| 116 | "r" (BW_LOCAL_BASE + BW_INTR_TABLE_CLEAR + (sbus_level << 3)), |
| 117 | "i" (ASI_M_CTL)); |
| 118 | } |
| 119 | |
| 120 | extern __inline__ unsigned bw_get_prof_limit(int cpu) |
| 121 | { |
| 122 | unsigned limit; |
| 123 | |
| 124 | __asm__ __volatile__ ("lda [%1] %2, %0" : |
| 125 | "=r" (limit) : |
| 126 | "r" (CSR_BASE(cpu) + BW_PTIMER_LIMIT), |
| 127 | "i" (ASI_M_CTL)); |
| 128 | return limit; |
| 129 | } |
| 130 | |
| 131 | extern __inline__ void bw_set_prof_limit(int cpu, unsigned limit) |
| 132 | { |
| 133 | __asm__ __volatile__ ("sta %0, [%1] %2" : : |
| 134 | "r" (limit), |
| 135 | "r" (CSR_BASE(cpu) + BW_PTIMER_LIMIT), |
| 136 | "i" (ASI_M_CTL)); |
| 137 | } |
| 138 | |
| 139 | extern __inline__ unsigned bw_get_ctrl(int cpu) |
| 140 | { |
| 141 | unsigned ctrl; |
| 142 | |
| 143 | __asm__ __volatile__ ("lda [%1] %2, %0" : |
| 144 | "=r" (ctrl) : |
| 145 | "r" (CSR_BASE(cpu) + BW_CTRL), |
| 146 | "i" (ASI_M_CTL)); |
| 147 | return ctrl; |
| 148 | } |
| 149 | |
| 150 | extern __inline__ void bw_set_ctrl(int cpu, unsigned ctrl) |
| 151 | { |
| 152 | __asm__ __volatile__ ("sta %0, [%1] %2" : : |
| 153 | "r" (ctrl), |
| 154 | "r" (CSR_BASE(cpu) + BW_CTRL), |
| 155 | "i" (ASI_M_CTL)); |
| 156 | } |
| 157 | |
| 158 | extern unsigned char cpu_leds[32]; |
| 159 | |
| 160 | extern __inline__ void show_leds(int cpuid) |
| 161 | { |
| 162 | cpuid &= 0x1e; |
| 163 | __asm__ __volatile__ ("stba %0, [%1] %2" : : |
| 164 | "r" ((cpu_leds[cpuid] << 4) | cpu_leds[cpuid+1]), |
| 165 | "r" (ECSR_BASE(cpuid) | BB_LEDS), |
| 166 | "i" (ASI_M_CTL)); |
| 167 | } |
| 168 | |
| 169 | extern __inline__ unsigned cc_get_ipen(void) |
| 170 | { |
| 171 | unsigned pending; |
| 172 | |
| 173 | __asm__ __volatile__ ("lduha [%1] %2, %0" : |
| 174 | "=r" (pending) : |
| 175 | "r" (CC_IPEN), |
| 176 | "i" (ASI_M_MXCC)); |
| 177 | return pending; |
| 178 | } |
| 179 | |
| 180 | extern __inline__ void cc_set_iclr(unsigned clear) |
| 181 | { |
| 182 | __asm__ __volatile__ ("stha %0, [%1] %2" : : |
| 183 | "r" (clear), |
| 184 | "r" (CC_ICLR), |
| 185 | "i" (ASI_M_MXCC)); |
| 186 | } |
| 187 | |
| 188 | extern __inline__ unsigned cc_get_imsk(void) |
| 189 | { |
| 190 | unsigned mask; |
| 191 | |
| 192 | __asm__ __volatile__ ("lduha [%1] %2, %0" : |
| 193 | "=r" (mask) : |
| 194 | "r" (CC_IMSK), |
| 195 | "i" (ASI_M_MXCC)); |
| 196 | return mask; |
| 197 | } |
| 198 | |
| 199 | extern __inline__ void cc_set_imsk(unsigned mask) |
| 200 | { |
| 201 | __asm__ __volatile__ ("stha %0, [%1] %2" : : |
| 202 | "r" (mask), |
| 203 | "r" (CC_IMSK), |
| 204 | "i" (ASI_M_MXCC)); |
| 205 | } |
| 206 | |
| 207 | extern __inline__ unsigned cc_get_imsk_other(int cpuid) |
| 208 | { |
| 209 | unsigned mask; |
| 210 | |
| 211 | __asm__ __volatile__ ("lduha [%1] %2, %0" : |
| 212 | "=r" (mask) : |
| 213 | "r" (ECSR_BASE(cpuid) | CC_IMSK), |
| 214 | "i" (ASI_M_CTL)); |
| 215 | return mask; |
| 216 | } |
| 217 | |
| 218 | extern __inline__ void cc_set_imsk_other(int cpuid, unsigned mask) |
| 219 | { |
| 220 | __asm__ __volatile__ ("stha %0, [%1] %2" : : |
| 221 | "r" (mask), |
| 222 | "r" (ECSR_BASE(cpuid) | CC_IMSK), |
| 223 | "i" (ASI_M_CTL)); |
| 224 | } |
| 225 | |
| 226 | extern __inline__ void cc_set_igen(unsigned gen) |
| 227 | { |
| 228 | __asm__ __volatile__ ("sta %0, [%1] %2" : : |
| 229 | "r" (gen), |
| 230 | "r" (CC_IGEN), |
| 231 | "i" (ASI_M_MXCC)); |
| 232 | } |
| 233 | |
| 234 | /* +-------+-------------+-----------+------------------------------------+ |
| 235 | * | bcast | devid | sid | levels mask | |
| 236 | * +-------+-------------+-----------+------------------------------------+ |
| 237 | * 31 30 23 22 15 14 0 |
| 238 | */ |
| 239 | #define IGEN_MESSAGE(bcast, devid, sid, levels) \ |
| 240 | (((bcast) << 31) | ((devid) << 23) | ((sid) << 15) | (levels)) |
| 241 | |
| 242 | extern __inline__ void sun4d_send_ipi(int cpu, int level) |
| 243 | { |
| 244 | cc_set_igen(IGEN_MESSAGE(0, cpu << 3, 6 + ((level >> 1) & 7), 1 << (level - 1))); |
| 245 | } |
| 246 | |
| 247 | #endif /* !__ASSEMBLY__ */ |
| 248 | |
| 249 | #endif /* !(_SPARC_OBIO_H) */ |