This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / arch / ia64 / sn / kernel / bte.c
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License.  See the file "COPYING" in the main directory of this archive
4  * for more details.
5  *
6  * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
7  */
8
9 #include <linux/config.h>
10 #include <linux/module.h>
11 #include <asm/sn/sgi.h>
12 #include <asm/sn/nodepda.h>
13 #include <asm/sn/addrs.h>
14 #include <asm/sn/arch.h>
15 #include <asm/sn/sn_cpuid.h>
16 #include <asm/sn/pda.h>
17 #include <asm/sn/sn2/shubio.h>
18 #include <asm/nodedata.h>
19 #include <asm/delay.h>
20
21 #include <linux/bootmem.h>
22 #include <linux/string.h>
23 #include <linux/sched.h>
24
25 #include <asm/sn/bte.h>
26
27 #ifndef L1_CACHE_MASK
28 #define L1_CACHE_MASK (L1_CACHE_BYTES - 1)
29 #endif
30
31 /* two interfaces on two btes */
32 #define MAX_INTERFACES_TO_TRY           4
33
34 static struct bteinfo_s *
35 bte_if_on_node(nasid_t nasid, int interface)
36 {
37         nodepda_t *tmp_nodepda;
38
39         tmp_nodepda = NODEPDA(nasid_to_cnodeid(nasid));
40         return &tmp_nodepda->bte_if[interface];
41
42 }
43
44
45 /************************************************************************
46  * Block Transfer Engine copy related functions.
47  *
48  ***********************************************************************/
49
50
51 /*
52  * bte_copy(src, dest, len, mode, notification)
53  *
54  * Use the block transfer engine to move kernel memory from src to dest
55  * using the assigned mode.
56  *
57  * Paramaters:
58  *   src - physical address of the transfer source.
59  *   dest - physical address of the transfer destination.
60  *   len - number of bytes to transfer from source to dest.
61  *   mode - hardware defined.  See reference information
62  *          for IBCT0/1 in the SHUB Programmers Reference
63  *   notification - kernel virtual address of the notification cache
64  *                  line.  If NULL, the default is used and
65  *                  the bte_copy is synchronous.
66  *
67  * NOTE:  This function requires src, dest, and len to
68  * be cacheline aligned.
69  */
70 bte_result_t
71 bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification)
72 {
73         u64 transfer_size;
74         struct bteinfo_s *bte;
75         bte_result_t bte_status;
76         unsigned long irq_flags;
77         struct bteinfo_s *btes_to_try[MAX_INTERFACES_TO_TRY];
78         int bte_if_index;
79
80
81         BTE_PRINTK(("bte_copy(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%p)\n",
82                     src, dest, len, mode, notification));
83
84         if (len == 0) {
85                 return BTE_SUCCESS;
86         }
87
88         ASSERT(!((len & L1_CACHE_MASK) ||
89                  (src & L1_CACHE_MASK) || (dest & L1_CACHE_MASK)));
90         ASSERT(len < ((BTE_LEN_MASK + 1) << L1_CACHE_SHIFT));
91
92         if (mode & BTE_USE_DEST) {
93                 /* try remote then local */
94                 btes_to_try[0] = bte_if_on_node(NASID_GET(dest), 0);
95                 btes_to_try[1] = bte_if_on_node(NASID_GET(dest), 1);
96                 if (mode & BTE_USE_ANY) {
97                         btes_to_try[2] = bte_if_on_node(get_nasid(), 0);
98                         btes_to_try[3] = bte_if_on_node(get_nasid(), 1);
99                 } else {
100                         btes_to_try[2] = NULL;
101                         btes_to_try[3] = NULL;
102                 }
103         } else {
104                 /* try local then remote */
105                 btes_to_try[0] = bte_if_on_node(get_nasid(), 0);
106                 btes_to_try[1] = bte_if_on_node(get_nasid(), 1);
107                 if (mode & BTE_USE_ANY) {
108                         btes_to_try[2] = bte_if_on_node(NASID_GET(dest), 0);
109                         btes_to_try[3] = bte_if_on_node(NASID_GET(dest), 1);
110                 } else {
111                         btes_to_try[2] = NULL;
112                         btes_to_try[3] = NULL;
113                 }
114         }
115
116         do {
117                 local_irq_save(irq_flags);
118
119                 bte_if_index = 0;
120
121                 /* Attempt to lock one of the BTE interfaces. */
122                 while (bte_if_index < MAX_INTERFACES_TO_TRY) {
123                         bte = btes_to_try[bte_if_index++];
124
125                         if (bte == NULL) {
126                                 continue;
127                         }
128
129                         if (spin_trylock(&bte->spinlock)) {
130                                 if ((*bte->most_rcnt_na & BTE_ACTIVE) ||
131                                     (BTE_LNSTAT_LOAD(bte) & BTE_ACTIVE)) {
132                                         /* Got the lock but BTE still busy */
133                                         spin_unlock(&bte->spinlock);
134                                         bte = NULL;
135                                 } else {
136                                         /* we got the lock and it's not busy */
137                                         break;
138                                 }
139                         }
140                 }
141
142                 if (bte != NULL) {
143                         break;
144                 }
145
146                 local_irq_restore(irq_flags);
147
148                 if (!(mode & BTE_WACQUIRE)) {
149                         return BTEFAIL_NOTAVAIL;
150                 }
151
152                 /* Wait until a bte is available. */
153                 udelay(1);
154         } while (1);
155
156
157         if (notification == NULL) {
158                 /* User does not want to be notified. */
159                 bte->most_rcnt_na = &bte->notify;
160         } else {
161                 bte->most_rcnt_na = notification;
162         }
163
164         /* Calculate the number of cache lines to transfer. */
165         transfer_size = ((len >> L1_CACHE_SHIFT) & BTE_LEN_MASK);
166
167         /* Initialize the notification to a known value. */
168         *bte->most_rcnt_na = -1L;
169
170         /* Set the status reg busy bit and transfer length */
171         BTE_PRINTKV(("IBLS = 0x%lx\n", IBLS_BUSY | transfer_size));
172         BTE_LNSTAT_STORE(bte, IBLS_BUSY | transfer_size);
173
174         /* Set the source and destination registers */
175         BTE_PRINTKV(("IBSA = 0x%lx)\n", (TO_PHYS(src))));
176         BTE_SRC_STORE(bte, TO_PHYS(src));
177         BTE_PRINTKV(("IBDA = 0x%lx)\n", (TO_PHYS(dest))));
178         BTE_DEST_STORE(bte, TO_PHYS(dest));
179
180         /* Set the notification register */
181         BTE_PRINTKV(("IBNA = 0x%lx)\n", 
182                      TO_PHYS(ia64_tpa((unsigned long)bte->most_rcnt_na))));
183         BTE_NOTIF_STORE(bte, TO_PHYS(ia64_tpa((unsigned long)bte->most_rcnt_na)));
184
185
186         /* Initiate the transfer */
187         BTE_PRINTK(("IBCT = 0x%lx)\n", BTE_VALID_MODE(mode)));
188         BTE_CTRL_STORE(bte, BTE_VALID_MODE(mode));
189
190         spin_unlock_irqrestore(&bte->spinlock, irq_flags);
191
192
193         if (notification != NULL) {
194                 return BTE_SUCCESS;
195         }
196
197         while (*bte->most_rcnt_na == -1UL) {
198         }
199
200
201         BTE_PRINTKV((" Delay Done.  IBLS = 0x%lx, most_rcnt_na = 0x%lx\n",
202                                 BTE_LNSTAT_LOAD(bte), *bte->most_rcnt_na));
203
204         if (*bte->most_rcnt_na & IBLS_ERROR) {
205                 bte_status = *bte->most_rcnt_na & ~IBLS_ERROR;
206                 *bte->most_rcnt_na = 0L;
207         } else {
208                 bte_status = BTE_SUCCESS;
209         }
210         BTE_PRINTK(("Returning status is 0x%lx and most_rcnt_na is 0x%lx\n",
211                                 BTE_LNSTAT_LOAD(bte), *bte->most_rcnt_na));
212
213         return bte_status;
214 }
215 EXPORT_SYMBOL(bte_copy);
216
217
218 /*
219  * bte_unaligned_copy(src, dest, len, mode)
220  *
221  * use the block transfer engine to move kernel
222  * memory from src to dest using the assigned mode.
223  *
224  * Paramaters:
225  *   src - physical address of the transfer source.
226  *   dest - physical address of the transfer destination.
227  *   len - number of bytes to transfer from source to dest.
228  *   mode - hardware defined.  See reference information
229  *          for IBCT0/1 in the SGI documentation.
230  *
231  * NOTE: If the source, dest, and len are all cache line aligned,
232  * then it would be _FAR_ preferrable to use bte_copy instead.
233  */
234 bte_result_t
235 bte_unaligned_copy(u64 src, u64 dest, u64 len, u64 mode)
236 {
237         int destFirstCacheOffset;
238         u64 headBteSource;
239         u64 headBteLen;
240         u64 headBcopySrcOffset;
241         u64 headBcopyDest;
242         u64 headBcopyLen;
243         u64 footBteSource;
244         u64 footBteLen;
245         u64 footBcopyDest;
246         u64 footBcopyLen;
247         bte_result_t rv;
248         char *bteBlock, *bteBlock_unaligned;
249
250         if (len == 0) {
251                 return BTE_SUCCESS;
252         }
253
254         /* temporary buffer used during unaligned transfers */
255         bteBlock_unaligned = kmalloc(len + 3 * L1_CACHE_BYTES,
256                                      GFP_KERNEL | GFP_DMA);
257         if (bteBlock_unaligned == NULL) {
258                 return BTEFAIL_NOTAVAIL;
259         }
260         bteBlock = (char *) L1_CACHE_ALIGN((u64) bteBlock_unaligned);
261
262         headBcopySrcOffset = src & L1_CACHE_MASK;
263         destFirstCacheOffset = dest & L1_CACHE_MASK;
264
265         /*
266          * At this point, the transfer is broken into
267          * (up to) three sections.  The first section is
268          * from the start address to the first physical
269          * cache line, the second is from the first physical
270          * cache line to the last complete cache line,
271          * and the third is from the last cache line to the
272          * end of the buffer.  The first and third sections
273          * are handled by bte copying into a temporary buffer
274          * and then bcopy'ing the necessary section into the
275          * final location.  The middle section is handled with
276          * a standard bte copy.
277          *
278          * One nasty exception to the above rule is when the
279          * source and destination are not symetrically
280          * mis-aligned.  If the source offset from the first
281          * cache line is different from the destination offset,
282          * we make the first section be the entire transfer
283          * and the bcopy the entire block into place.
284          */
285         if (headBcopySrcOffset == destFirstCacheOffset) {
286
287                 /*
288                  * Both the source and destination are the same
289                  * distance from a cache line boundary so we can
290                  * use the bte to transfer the bulk of the
291                  * data.
292                  */
293                 headBteSource = src & ~L1_CACHE_MASK;
294                 headBcopyDest = dest;
295                 if (headBcopySrcOffset) {
296                         headBcopyLen =
297                             (len >
298                              (L1_CACHE_BYTES -
299                               headBcopySrcOffset) ? L1_CACHE_BYTES
300                              - headBcopySrcOffset : len);
301                         headBteLen = L1_CACHE_BYTES;
302                 } else {
303                         headBcopyLen = 0;
304                         headBteLen = 0;
305                 }
306
307                 if (len > headBcopyLen) {
308                         footBcopyLen =
309                             (len - headBcopyLen) & L1_CACHE_MASK;
310                         footBteLen = L1_CACHE_BYTES;
311
312                         footBteSource = src + len - footBcopyLen;
313                         footBcopyDest = dest + len - footBcopyLen;
314
315                         if (footBcopyDest ==
316                             (headBcopyDest + headBcopyLen)) {
317                                 /*
318                                  * We have two contigous bcopy
319                                  * blocks.  Merge them.
320                                  */
321                                 headBcopyLen += footBcopyLen;
322                                 headBteLen += footBteLen;
323                         } else if (footBcopyLen > 0) {
324                                 rv = bte_copy(footBteSource,
325                                               ia64_tpa((unsigned long)bteBlock),
326                                               footBteLen, mode, NULL);
327                                 if (rv != BTE_SUCCESS) {
328                                         kfree(bteBlock_unaligned);
329                                         return rv;
330                                 }
331
332
333                                 memcpy(__va(footBcopyDest),
334                                        (char *) bteBlock, footBcopyLen);
335                         }
336                 } else {
337                         footBcopyLen = 0;
338                         footBteLen = 0;
339                 }
340
341                 if (len > (headBcopyLen + footBcopyLen)) {
342                         /* now transfer the middle. */
343                         rv = bte_copy((src + headBcopyLen),
344                                       (dest +
345                                        headBcopyLen),
346                                       (len - headBcopyLen -
347                                        footBcopyLen), mode, NULL);
348                         if (rv != BTE_SUCCESS) {
349                                 kfree(bteBlock_unaligned);
350                                 return rv;
351                         }
352
353                 }
354         } else {
355
356
357                 /*
358                  * The transfer is not symetric, we will
359                  * allocate a buffer large enough for all the
360                  * data, bte_copy into that buffer and then
361                  * bcopy to the destination.
362                  */
363
364                 /* Add the leader from source */
365                 headBteLen = len + (src & L1_CACHE_MASK);
366                 /* Add the trailing bytes from footer. */
367                 headBteLen +=
368                     L1_CACHE_BYTES - (headBteLen & L1_CACHE_MASK);
369                 headBteSource = src & ~L1_CACHE_MASK;
370                 headBcopySrcOffset = src & L1_CACHE_MASK;
371                 headBcopyDest = dest;
372                 headBcopyLen = len;
373         }
374
375         if (headBcopyLen > 0) {
376                 rv = bte_copy(headBteSource,
377                               ia64_tpa((unsigned long)bteBlock), headBteLen, mode, NULL);
378                 if (rv != BTE_SUCCESS) {
379                         kfree(bteBlock_unaligned);
380                         return rv;
381                 }
382
383                 memcpy(__va(headBcopyDest), ((char *) bteBlock +
384                                              headBcopySrcOffset),
385                        headBcopyLen);
386         }
387         kfree(bteBlock_unaligned);
388         return BTE_SUCCESS;
389 }
390 EXPORT_SYMBOL(bte_unaligned_copy);
391
392
393 /************************************************************************
394  * Block Transfer Engine initialization functions.
395  *
396  ***********************************************************************/
397
398
399 /*
400  * bte_init_node(nodepda, cnode)
401  *
402  * Initialize the nodepda structure with BTE base addresses and
403  * spinlocks.
404  */
405 void
406 bte_init_node(nodepda_t * mynodepda, cnodeid_t cnode)
407 {
408         int i;
409
410
411         /*
412          * Indicate that all the block transfer engines on this node
413          * are available.
414          */
415
416         /*
417          * Allocate one bte_recover_t structure per node.  It holds
418          * the recovery lock for node.  All the bte interface structures
419          * will point at this one bte_recover structure to get the lock.
420          */
421         spin_lock_init(&mynodepda->bte_recovery_lock);
422         init_timer(&mynodepda->bte_recovery_timer);
423         mynodepda->bte_recovery_timer.function = bte_error_handler;
424         mynodepda->bte_recovery_timer.data = (unsigned long) mynodepda;
425
426         for (i = 0; i < BTES_PER_NODE; i++) {
427                 (u64) mynodepda->bte_if[i].bte_base_addr =
428                     REMOTE_HUB_ADDR(cnodeid_to_nasid(cnode),
429                         (i == 0 ? IIO_IBLS0 : IIO_IBLS1));
430
431                 /*
432                  * Initialize the notification and spinlock
433                  * so the first transfer can occur.
434                  */
435                 mynodepda->bte_if[i].most_rcnt_na =
436                     &(mynodepda->bte_if[i].notify);
437                 mynodepda->bte_if[i].notify = 0L;
438                 spin_lock_init(&mynodepda->bte_if[i].spinlock);
439
440                 mynodepda->bte_if[i].bte_cnode = cnode;
441                 mynodepda->bte_if[i].bte_error_count = 0;
442                 mynodepda->bte_if[i].bte_num = i;
443                 mynodepda->bte_if[i].cleanup_active = 0;
444                 mynodepda->bte_if[i].bh_error = 0;
445         }
446
447 }