OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [ppc/] [kernel/] [misc.S] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1624 jcastillo
/*
2
 * This module contains the PowerPC interrupt fielders
3
 * set of code at specific locations, based on function
4
 */
5
 
6
#include 
7
#include "ppc_asm.tmpl"
8
 
9
/* Keep track of low-level exceptions - rather crude, but informative */
10
#define STATS
11
 
12
/*
13
 * Increment a [64 bit] statistic counter
14
 * Uses R2, R3
15
 */
16
#define BUMP(ctr) \
17
        lis     r2,ctr@h; \
18
        ori     r2,r2,ctr@l; \
19
        lwz     r3,4(r2); \
20
        addic   r3,r3,1; \
21
        stw     r3,4(r2); \
22
        lwz     r3,0(r2); \
23
        addze   r3,r3; \
24
        stw     r3,0(r2)
25
 
26
/* This instruction is not implemented on the PPC 603 */
27
#define tlbia \
28
        li      r4,64; \
29
        mtspr   CTR,r4; \
30
        li      r4,0; \
31
0:      tlbie   r4; \
32
        addi    r4,r4,0x1000; \
33
        bdnz    0b
34
 
35
_TEXT()
36
 
37
/*
38
 * Disable interrupts
39
 *      rc = _disable_interrupts()
40
 */
41
_GLOBAL(_disable_interrupts)
42
        mfmsr   r0              /* Get current interrupt state */
43
        rlwinm  r3,r0,16+1,32-1,31      /* Extract old value of 'EE' */
44
        li      r4,0            /* Need [unsigned] value of MSR_EE */
45
        ori     r4,r4,MSR_EE    /* Set to turn off bit */
46
        andc    r0,r0,r4        /* Clears bit in (r4) */
47
        sync                    /* Some chip revs have problems here... */
48
        mtmsr   r0              /* Update machine state */
49
        blr                     /* Done */
50
 
51
/*
52
 * Enable interrupts
53
 *      _enable_interrupts(int state)
54
 * turns on interrupts if state = 1.
55
 */
56
_GLOBAL(_enable_interrupts)
57
        mfmsr   r0              /* Get current state */
58
        rlwimi  r0,r3,16-1,32-16,32-16  /* Insert bit */
59
        sync                    /* Some chip revs have problems here... */
60
        mtmsr   r0              /* Update machine state */
61
        blr
62
 
63
/*
64
 * Get 'flags' (aka machine status register)
65
 *      __save_flags(long *ptr)
66
 */
67
_GLOBAL(__save_flags)
68
        mfmsr   r0              /* Get current state */
69
        stw     r0,0(r3)
70
        mr      r3,r0
71
        blr
72
 
73
/*
74
 * Restore 'flags'
75
 *      __restore_flags(long val)
76
 */
77
_GLOBAL(__restore_flags)
78
        sync                    /* Some chip revs have problems here... */
79
        mtmsr   r3
80
        isync
81
        blr
82
 
83
/*
84
 * Disable interrupts - like an 80x86
85
 *      cli()
86
 */
87
_GLOBAL(cli)
88
        mfmsr   r0              /* Get current interrupt state */
89
        rlwinm  r3,r0,16+1,32-1,31      /* Extract old value of 'EE' */
90
        li      r4,0            /* Need [unsigned] value of MSR_EE */
91
        ori     r4,r4,MSR_EE    /* Set to turn off bit */
92
        andc    r0,r0,r4        /* Clears bit in (r4) */
93
        sync                    /* Some chip revs have problems here... */
94
        mtmsr   r0              /* Update machine state */
95
        blr                     /* Done */
96
 
97
/*
98
 * Enable interrupts - like an 80x86
99
 *      sti()
100
 */
101
_GLOBAL(sti)
102
        mfmsr   r0              /* Get current state */
103
        ori     r0,r0,MSR_EE    /* Turn on 'EE' bit */
104
        sync                    /* Some chip revs have problems here... */
105
        mtmsr   r0              /* Update machine state */
106
        blr
107
 
108
/*
109
 * Flush MMU TLB
110
 */
111
_GLOBAL(_tlbia)
112
        tlbia
113
        BUMP(__TLBIAs)
114
        blr
115
 
116
/*
117
 * Flush MMU TLB for a particular address
118
 */
119
_GLOBAL(_tlbie)
120
        tlbie   r3
121
        BUMP(__TLBIEs)
122
        blr
123
 
124
/*
125
 * Fetch the current SR register
126
 *   get_SR(int index)
127
 */
128
_GLOBAL(get_SR)
129
        mfsrin  r3,r3
130
        blr
131
 
132
/*
133
 * Atomic [test&set] exchange
134
 *
135
 *      void *xchg_u32(void *ptr, unsigned long val)
136
 * Changes the memory location '*ptr' to be val and returns
137
 * the previous value stored there.
138
 */
139
_GLOBAL(xchg_u32)
140
        mr      r5,r3           /* Save pointer */
141
10:     lwarx   r3,0,r5         /* Fetch old value & reserve */
142
        stwcx.  r4,0,r5         /* Update with new value */
143
        bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
144
        blr
145
 
146
/*
147
 * Atomic add/sub/inc/dec operations
148
 *
149
 * void atomic_add(int c, int *v)
150
 * void atomic_sub(int c, int *v)
151
 * void atomic_inc(int *v)
152
 * void atomic_dec(int *v)
153
 * void atomic_dec_and_test(int *v)
154
 */
155
_GLOBAL(atomic_add)
156
10:     lwarx   r5,0,r4         /* Fetch old value & reserve */
157
        add     r5,r5,r3        /* Perform 'add' operation */
158
        stwcx.  r5,0,r4         /* Update with new value */
159
        bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
160
        blr
161
_GLOBAL(atomic_sub)
162
10:     lwarx   r5,0,r4         /* Fetch old value & reserve */
163
        sub     r5,r5,r3        /* Perform 'add' operation */
164
        stwcx.  r5,0,r4         /* Update with new value */
165
        bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
166
        blr
167
_GLOBAL(atomic_inc)
168
10:     lwarx   r5,0,r3         /* Fetch old value & reserve */
169
        addi    r5,r5,1         /* Perform 'add' operation */
170
        stwcx.  r5,0,r3         /* Update with new value */
171
        bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
172
        blr
173
_GLOBAL(atomic_dec)
174
10:     lwarx   r5,0,r3         /* Fetch old value & reserve */
175
        subi    r5,r5,1         /* Perform 'add' operation */
176
        stwcx.  r5,0,r3         /* Update with new value */
177
        bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
178
        blr
179
_GLOBAL(atomic_dec_and_test)
180
10:     lwarx   r5,0,r3         /* Fetch old value & reserve */
181
        subi    r5,r5,1         /* Perform 'add' operation */
182
        stwcx.  r5,0,r3         /* Update with new value */
183
        bne-    10b             /* Retry if "reservation" (i.e. lock) lost */
184
        cmpi    0,r5,0          /* Return 'true' IFF 0 */
185
        bne     15f
186
        li      r3,1
187
        blr
188
15:     li      r3,0
189
        blr
190
 
191
 
192
/*
193
 * Delay for a specific # of "loops"
194
 *      __delay(int loops)
195
 */
196
_GLOBAL(__delay)
197
        mtctr   r3
198
00:     addi    r3,r3,0         /* NOP */
199
        bdnz    00b
200
        blr
201
 
202
/*
203
 * Delay for a number of microseconds
204
 *      udelay(int usecs)
205
 */
206
_GLOBAL(udelay)
207
00:     li      r0,86   /* Instructions / microsecond? */
208
        mtctr   r0
209
10:     addi    r0,r0,0 /* NOP */
210
        bdnz    10b
211
        subic.  r3,r3,1
212
        bne     00b
213
        blr
214
 
215
/*
216
 * Atomically increment [intr_count]
217
 */
218
_GLOBAL(start_bh_atomic)
219
        lis     r3,intr_count@h
220
        ori     r3,r3,intr_count@l
221
10:     lwarx   r4,0,r3
222
        addi    r4,r4,1
223
        stwcx.  r4,0,r3
224
        bne-    10b
225
        blr
226
 
227
/*
228
 * Atomically decrement [intr_count]
229
 */
230
_GLOBAL(end_bh_atomic)
231
        lis     r3,intr_count@h
232
        ori     r3,r3,intr_count@l
233
10:     lwarx   r4,0,r3
234
        subic   r4,r4,1
235
        stwcx.  r4,0,r3
236
        bne-    10b
237
        blr
238
 
239
/*
240
 * I/O string operations
241
 *
242
 * insw(port, buf, len)
243
 * outsw(port, buf, len)
244
 */
245
_GLOBAL(_insw)
246
        mtctr   r5
247
        subi    r4,r4,2
248
00:     lhbrx   r5,0,r3
249
        sthu    r5,2(r4)
250
        bdnz    00b
251
        blr
252
 
253
_GLOBAL(_outsw)
254
        mtctr   r5
255
        subi    r4,r4,2
256
00:     lhzu    r5,2(r4)
257
        sthbrx  r5,0,r3
258
        bdnz    00b
259
        blr
260
 
261
#if 0
262
/*
263
 *extern inline int find_first_zero_bit(void * vaddr, unsigned size)
264
 *{
265
 *      unsigned long res;
266
 *      unsigned long *p;
267
 *      unsigned long *addr = vaddr;
268
 *
269
 *      if (!size)
270
 *              return 0;
271
 *      __asm__ __volatile__ ("    moveq #-1,d0\n\t"
272
 *                            "1:"
273
 *                            "    cmpl  %1@+,d0\n\t"
274
 *                            "    bne   2f\n\t"
275
 *                            "    subql #1,%0\n\t"
276
 *                            "    bne   1b\n\t"
277
 *                            "    bra   5f\n\t"
278
 *                            "2:"
279
 *                            "    movel %1@-,d0\n\t"
280
 *                            "    notl  d0\n\t"
281
 *                            "    bfffo d0{#0,#0},%0\n\t"
282
 *                            "5:"
283
 *                            : "=d" (res), "=a" (p)
284
 *                            : "0" ((size + 31) >> 5), "1" (addr)
285
 *                            : "d0");
286
 *      return ((p - addr) << 5) + res;
287
 *}
288
 */
289
_GLOBAL(find_first_zero_bit)
290
        li      r5,0            /* bit # */
291
        subi    r3,r3,4         /* Adjust pointer for auto-increment */
292
00:     lwzu    r0,4(r3)        /* Get next word */
293
        not.    r7,r0           /* Complement to find ones */
294
        beq     10f             /* Jump if all ones */
295
02:     andi.   r7,r0,1         /* Check low-order bit */
296
        beq     20f             /* All done when zero found */
297
        srawi   r0,r0,1
298
        addi    r5,r5,1
299
        b       02b
300
10:     addi    r5,r5,32        /* Update bit # */
301
        subic.  r4,r4,32        /* Any more? */
302
        bgt     00b
303
20:     mr      r3,r5           /* Compute result */
304
        blr
305
 
306
/*
307
 *static inline int find_next_zero_bit (void *vaddr, int size,
308
 *                                    int offset)
309
 *{
310
 *      unsigned long *addr = vaddr;
311
 *      unsigned long *p = addr + (offset >> 5);
312
 *      int set = 0, bit = offset & 31, res;
313
 *
314
 *      if (bit) {
315
 *              // Look for zero in first longword
316
 *              __asm__("bfffo %1{#0,#0},%0"
317
 *                      : "=d" (set)
318
 *                      : "d" (~*p << bit));
319
 *              if (set < (32 - bit))
320
 *                      return set + offset;
321
 *                set = 32 - bit;
322
 *              p++;
323
 *      }
324
 *      // No zero yet, search remaining full bytes for a zero
325
 *      res = find_first_zero_bit (p, size - 32 * (p - addr));
326
 *      return (offset + set + res);
327
 *}
328
 */
329
_GLOBAL(find_next_zero_bit)
330
        addi    r5,r5,1         /* bump offset to start */
331
        srawi   r6,r5,5         /* word offset */
332
        add     r6,r6,r6        /* byte offset */
333
        add     r6,r6,r6        /* byte offset */
334
        add     r3,r3,r6        /* compute byte position */
335
        sub     r4,r4,r5        /* adjust size by starting index */
336
        andi.   r0,r5,0x1F      /* offset in current word? */
337
        beq     10f             /* at start of word */
338
        lwz     r0,0(r3)        /* get word */
339
        sraw    r0,r0,r5        /* shift right */
340
        not.    r7,r0
341
        beq     07f             /* jump if only ones remain */
342
05:     andi.   r7,r0,1         /* found zero? */
343
        beq     90f             /* yes - all done */
344
        srawi   r0,r0,1
345
        addi    r5,r5,1
346
        b       05b
347
07:     andi.   r6,r5,0x1F
348
        subfic  r0,r6,32
349
        add     r5,r5,r0
350
        sub     r4,r4,r0
351
        b       20f
352
10:     subi    r3,r3,4         /* Adjust pointer for auto-increment */
353
20:     lwzu    r0,4(r3)        /* Get next word */
354
        not.    r7,r0           /* Complement to find ones */
355
        beq     40f             /* Jump if all ones */
356
30:     andi.   r7,r0,1         /* Check low-order bit */
357
        beq     90f             /* All done when zero found */
358
        srawi   r0,r0,1
359
        addi    r5,r5,1
360
        b       30b
361
40:     addi    r5,r5,32        /* Update bit # */
362
        subic.  r4,r4,32        /* Any more? */
363
        bgt     20b
364
90:     mr      r3,r5           /* Compute result */
365
        blr
366
#endif
367
 
368
/*
369
 *
370
 * ffz = Find First Zero in word. Undefined if no zero exists,
371
 * so code should check against ~0UL first..
372
 *
373
 *extern inline unsigned long ffz(unsigned long word)
374
 *{
375
 *      __asm__ __volatile__ ("bfffo %1{#0,#0},%0"
376
 *                            : "=d" (word)
377
 *                            : "d" (~(word)));
378
 *      return word;
379
 *}
380
 */
381
_GLOBAL(ffz)
382
        mr      r4,r3
383
        li      r3,0
384
10:     andi.   r0,r4,1         /* Find the zero we know is there */
385
        srawi   r4,r4,1
386
        beq     90f
387
        addi    r3,r3,1
388
        b       10b
389
90:     blr
390
 
391
/*
392
 * Extended precision shifts
393
 *
394
 * R3/R4 has 64 bit value
395
 * R5    has shift count
396
 * result in R3/R4
397
 *
398
 *  ashrdi3:     XXXYYY/ZZZAAA -> SSSXXX/YYYZZZ
399
 *  ashldi3:     XXXYYY/ZZZAAA -> YYYZZZ/AAA000
400
 */
401
_GLOBAL(__ashrdi3)
402
        li      r6,32
403
        sub     r6,r6,r5
404
        slw     r7,r3,r6        /* isolate YYY */
405
        srw     r4,r4,r5        /* isolate ZZZ */
406
        or      r4,r4,r7        /* YYYZZZ */
407
        sraw    r3,r3,r5        /* SSSXXX */
408
        blr
409
 
410
_GLOBAL(__ashldi3)
411
        li      r6,32
412
        sub     r6,r6,r5
413
        srw     r7,r4,r6        /* isolate ZZZ */
414
        slw     r4,r4,r5        /* AAA000 */
415
        slw     r3,r3,r5        /* YYY--- */
416
        or      r3,r3,r7        /* YYYZZZ */
417
        blr
418
 
419
_GLOBAL(abort)
420
        .long   0
421
 
422
_GLOBAL(bzero)
423
#define bufp r3
424
#define len  r4
425
#define pat  r5
426
/* R3 has buffer */
427
/* R4 has length */
428
/* R5 has pattern */
429
        cmpi    0,len,0         /* Exit if len <= 0 */
430
        ble     99f
431
        andi.   r0,bufp,3       /* Must be on longword boundary */
432
        bne     10f             /* Use byte loop if not aligned */
433
        andi.   r0,len,3        /* Check for overrage */
434
        subi    bufp,bufp,4     /* Adjust pointer */
435
        srawi   len,len,2       /* Divide by 4 */
436
        blt     99f             /* If negative - bug out! */
437
        mtspr   CTR,len         /* Set up counter */
438
        li      pat,0
439
00:     stwu    pat,4(bufp)     /* Store value */
440
        bdnz    00b             /* Loop [based on counter] */
441
        mr      len,r0          /* Get remainder (bytes) */
442
10:     cmpi    0,len,0         /* Any bytes left */
443
        ble     99f             /* No - all done */
444
        mtspr   CTR,len         /* Set up counter */
445
        subi    bufp,bufp,1     /* Adjust pointer */
446
        li      pat,0
447
20:     stbu    pat,1(bufp)     /* Store value */
448
        bdnz    20b             /* Loop [based on counter] */
449
99:     blr
450
 
451
_GLOBAL(abs)
452
        cmpi    0,r3,0
453
        bge     10f
454
        neg     r3,r3
455
10:     blr
456
 
457
_GLOBAL(_get_SP)
458
        mr      r3,r1           /* Close enough */
459
        blr
460
 
461
_GLOBAL(_get_SDR1)
462
        mfspr   r3,SDR1
463
        blr
464
 
465
_GLOBAL(_get_SRx)
466
        mfsrin  r3,r3
467
        blr
468
 
469
_GLOBAL(_get_PVR)
470
        mfspr   r3,PVR
471
        blr
472
 
473
/*
474
 * Create a kernel thread
475
 *   __kernel_thread(flags, fn, arg)
476
 */
477
#if 0
478
#define SYS_CLONE       120
479
_GLOBAL(__kernel_thread)
480
__kernel_thread:
481
        li      r0,SYS_CLONE
482
        sc
483
        cmpi    0,r3,0
484
        bnelr
485
        mtlr    r4
486
        mr      r3,r5
487
        blr
488
#endif
489
/* Why isn't this a) automatic, b) written in 'C'? */
490
        .data
491
        .align 4
492
        .globl  sys_call_table
493
sys_call_table:
494
        .long sys_setup         /* 0 */
495
        .long sys_exit
496
        .long sys_fork
497
        .long sys_read
498
        .long sys_write
499
        .long sys_open                  /* 5 */
500
        .long sys_close
501
        .long sys_waitpid
502
        .long sys_creat
503
        .long sys_link
504
        .long sys_unlink                /* 10 */
505
        .long sys_execve
506
        .long sys_chdir
507
        .long sys_time
508
        .long sys_mknod
509
        .long sys_chmod         /* 15 */
510
        .long sys_chown
511
        .long sys_break
512
        .long sys_stat
513
        .long sys_lseek
514
        .long sys_getpid                /* 20 */
515
        .long sys_mount
516
        .long sys_umount
517
        .long sys_setuid
518
        .long sys_getuid
519
        .long sys_stime         /* 25 */
520
        .long sys_ptrace
521
        .long sys_alarm
522
        .long sys_fstat
523
        .long sys_pause
524
        .long sys_utime         /* 30 */
525
        .long sys_stty
526
        .long sys_gtty
527
        .long sys_access
528
        .long sys_nice
529
        .long sys_ftime         /* 35 */
530
        .long sys_sync
531
        .long sys_kill
532
        .long sys_rename
533
        .long sys_mkdir
534
        .long sys_rmdir         /* 40 */
535
        .long sys_dup
536
        .long sys_pipe
537
        .long sys_times
538
        .long sys_prof
539
        .long sys_brk                   /* 45 */
540
        .long sys_setgid
541
        .long sys_getgid
542
        .long sys_signal
543
        .long sys_geteuid
544
        .long sys_getegid               /* 50 */
545
        .long sys_acct
546
        .long sys_phys
547
        .long sys_lock
548
        .long sys_ioctl
549
        .long sys_fcntl         /* 55 */
550
        .long sys_mpx
551
        .long sys_setpgid
552
        .long sys_ulimit
553
        .long sys_olduname
554
        .long sys_umask         /* 60 */
555
        .long sys_chroot
556
        .long sys_ustat
557
        .long sys_dup2
558
        .long sys_getppid
559
        .long sys_getpgrp               /* 65 */
560
        .long sys_setsid
561
        .long sys_sigaction
562
        .long sys_sgetmask
563
        .long sys_ssetmask
564
        .long sys_setreuid              /* 70 */
565
        .long sys_setregid
566
        .long sys_sigsuspend
567
        .long sys_sigpending
568
        .long sys_sethostname
569
        .long sys_setrlimit             /* 75 */
570
        .long sys_getrlimit
571
        .long sys_getrusage
572
        .long sys_gettimeofday
573
        .long sys_settimeofday
574
        .long sys_getgroups             /* 80 */
575
        .long sys_setgroups
576
        .long sys_select
577
        .long sys_symlink
578
        .long sys_lstat
579
        .long sys_readlink              /* 85 */
580
        .long sys_uselib
581
        .long sys_swapon
582
        .long sys_reboot
583
        .long old_readdir               /* was sys_readdir */
584
        .long sys_mmap                  /* 90 */
585
        .long sys_munmap
586
        .long sys_truncate
587
        .long sys_ftruncate
588
        .long sys_fchmod
589
        .long sys_fchown                /* 95 */
590
        .long sys_getpriority
591
        .long sys_setpriority
592
        .long sys_profil
593
        .long sys_statfs
594
        .long sys_fstatfs               /* 100 */
595
        .long sys_ioperm
596
        .long sys_socketcall
597
        .long sys_syslog
598
        .long sys_setitimer
599
        .long sys_getitimer             /* 105 */
600
        .long sys_newstat
601
        .long sys_newlstat
602
        .long sys_newfstat
603
        .long sys_uname
604
        .long sys_iopl                  /* 110 */
605
        .long sys_vhangup
606
        .long sys_idle
607
        .long sys_vm86
608
        .long sys_wait4
609
        .long sys_swapoff               /* 115 */
610
        .long sys_sysinfo
611
        .long sys_ipc
612
        .long sys_fsync
613
        .long sys_sigreturn
614
        .long sys_clone         /* 120 */
615
        .long sys_setdomainname
616
        .long sys_newuname
617
        .long sys_modify_ldt
618
        .long sys_adjtimex
619
        .long sys_mprotect              /* 125 */
620
        .long sys_sigprocmask
621
        .long sys_create_module
622
        .long sys_init_module
623
        .long sys_delete_module
624
        .long sys_get_kernel_syms       /* 130 */
625
        .long sys_quotactl
626
        .long sys_getpgid
627
        .long sys_fchdir
628
        .long sys_bdflush
629
        .long sys_sysfs         /* 135 */
630
        .long sys_personality
631
        .long 0                         /* for afs_syscall */
632
        .long sys_setfsuid
633
        .long sys_setfsgid
634
        .long sys_llseek                /* 140 */
635
        .long sys_getdents
636
        .long sys_newselect
637
        .long sys_flock
638
        .long sys_msync
639
        .long sys_readv         /* 145 */
640
        .long sys_writev
641
        .long sys_getsid
642
        .long sys_fdatasync
643
        .long sys_sysctl
644
        .long sys_mlock         /* 150 */
645
        .long sys_munlock
646
        .long sys_mlockall
647
        .long sys_munlockall
648
        .long sys_sched_setparam
649
        .long sys_sched_getparam   /* 155 */
650
        .long sys_sched_setscheduler
651
        .long sys_sched_getscheduler
652
        .long sys_sched_yield
653
        .long sys_sched_get_priority_max
654
        .long sys_sched_get_priority_min  /* 160 */
655
        .long sys_sched_rr_get_interval
656
        .long sys_nanosleep
657
        .long sys_mremap
658
        .space (NR_syscalls-163)*4
659
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.