#if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE)
.align 4
.globl floppy_hardint
floppy_hardint: /* * This code cannot touch registers %l0 %l1 and %l2 * because SAVE_ALL depends on their values. It depends * on %l3 also, but we regenerate it before a call. * Other registers are: * %l3 -- base address of fdc registers * %l4 -- pdma_vaddr * %l5 -- scratch for ld/st address * %l6 -- pdma_size * %l7 -- scratch [floppy byte, ld/st address, aux. data]
*/
/* Do we have work to do? */ sethi %hi(doing_pdma), %l7 ld [%l7 + %lo(doing_pdma)], %l7
cmp %l7, 0
be floppy_dosoftint
nop
2: /* Kill some time so the bits set */
WRITE_PAUSE
WRITE_PAUSE
stb %l5, [%l7]
/* Prevent recursion */ sethi %hi(doing_pdma), %l7
b floppy_dosoftint st %g0, [%l7 + %lo(doing_pdma)]
/* We emptied the FIFO, but we haven't read everything * as of yet. Store the current transfer address and * bytes left to read so we can continue when the next * fast IRQ comes in.
*/
floppy_fifo_emptied: sethi %hi(pdma_vaddr), %l5 st %l4, [%l5 + %lo(pdma_vaddr)] sethi %hi(pdma_size), %l7 st %l6, [%l7 + %lo(pdma_size)]
/* For now all IRQ's not registered get sent here. handler_irq() will * see if a routine is registered to handle this interrupt and if not * it will say so on the console.
*/
/* Advance over the trap instruction. */ ld [%sp + STACKFRAME_SZ + PT_NPC], %l1
add %l1, 0x4, %l2 st %l1, [%sp + STACKFRAME_SZ + PT_PC] st %l2, [%sp + STACKFRAME_SZ + PT_NPC]
RESTORE_ALL
.globl flush_patch_one
/* We get these for debugging routines using __builtin_return_address() */
dfw_kernel:
flush_patch_one:
FLUSH_ALL_KERNEL_WINDOWS
/* Advance over the trap instruction. */ ld [%sp + STACKFRAME_SZ + PT_NPC], %l1
add %l1, 0x4, %l2 st %l1, [%sp + STACKFRAME_SZ + PT_PC] st %l2, [%sp + STACKFRAME_SZ + PT_NPC]
RESTORE_ALL
/* The getcc software trap. The user wants the condition codes from * the %psr in register %g1.
*/
.align 4
.globl getcc_trap_handler
getcc_trap_handler: srl %l0, 20, %g1 ! give user
and %g1, 0xf, %g1 ! only ICC bits in %psr
jmp %l2 ! advance over trap instruction
rett %l2 + 0x4 ! like this...
/* The setcc software trap. The user has condition codes in %g1 * that it would like placed in the %psr. Be careful not to flip * any unintentional bits!
*/
.align 4
.globl setcc_trap_handler
setcc_trap_handler: sll %g1, 0x14, %l4 set PSR_ICC, %l5
andn %l0, %l5, %l0 ! clear ICC bits in %psr
and %l4, %l5, %l4 ! clear non-ICC bits in user value
or %l4, %l0, %l4 ! or them in... mix mix mix
wr %l4, 0x0, %psr ! set new %psr
WRITE_PAUSE ! TI scumbags...
jmp %l2 ! advance over trap instruction
rett %l2 + 0x4 ! like this...
1: /* We are returning to a signal handler. */
RESTORE_ALL
/* Now that we have a real sys_clone, sys_fork() is * implemented in terms of it. Our _real_ implementation * of SunOS vfork() will use sys_vfork(). * * XXX These three should be consolidated into mostly shared * XXX code just like on sparc64... -DaveM
*/
.align 4
.globl sys_fork, flush_patch_two
sys_fork:
mov %o7, %l5
flush_patch_two:
FLUSH_ALL_KERNEL_WINDOWS; ld [%curptr + TI_TASK], %o4
rd %psr, %g4
WRITE_PAUSE
rd %wim, %g5
WRITE_PAUSE
std %g4, [%o4 + AOFF_task_thread + AOFF_thread_fork_kpsr]
add %sp, STACKFRAME_SZ, %o0
call sparc_fork
mov %l5, %o7
/* Saving and restoring the FPU state is best done from lowlevel code. * * void fpsave(unsigned long *fpregs, unsigned long *fsr, * void *fpqueue, unsigned long *fpqdepth)
*/
.globl fpsave
fpsave: st %fsr, [%o1] ! this can trap on us if fpu is in bogon state ld [%o1], %g1 set 0x2000, %g4
andcc %g1, %g4, %g0
be 2f
mov 0, %g2
/* We have an fpqueue to save. */
1:
std %fq, [%o2]
fpsave_magic: st %fsr, [%o1] ld [%o1], %g3
andcc %g3, %g4, %g0
add %g2, 1, %g2
bne 1b
add %o2, 8, %o2
/* Thanks for Theo Deraadt and the authors of the Sprite/netbsd/openbsd * code for pointing out this possible deadlock, while we save state * above we could trap on the fsr store so our low level fpu trap * code has to know how to deal with this.
*/
fpsave_catch:
b fpsave_magic + 4 st %fsr, [%o1]
fpsave_catch2:
b fpsave + 4 st %fsr, [%o1]
/* void fpload(unsigned long *fpregs, unsigned long *fsr); */
/* __ndelay and __udelay take two arguments: * 0 - nsecs or usecs to delay * 1 - per_cpu udelay_val (loops per jiffy) * * Note that ndelay gives HZ times higher resolution but has a 10ms * limit. udelay can handle up to 1s.
*/
.globl __ndelay
__ndelay:
save %sp, -STACKFRAME_SZ, %sp
mov %i0, %o0 ! round multiplier up so large ns ok
mov 0x1ae, %o1 ! 2**32 / (1 000 000 000 / HZ)
umul %o0, %o1, %o0
rd %y, %o1
mov %i1, %o1 ! udelay_val
umul %o0, %o1, %o0
rd %y, %o1
ba delay_continue
mov %o1, %o0 ! >>32 later for better resolution
.globl __udelay
__udelay:
save %sp, -STACKFRAME_SZ, %sp
mov %i0, %o0 sethi %hi(0x10c7), %o1 ! round multiplier up so large us ok
or %o1, %lo(0x10c7), %o1 ! 2**32 / 1 000 000
umul %o0, %o1, %o0
rd %y, %o1
mov %i1, %o1 ! udelay_val
umul %o0, %o1, %o0
rd %y, %o1 sethi %hi(0x028f4b62), %l0 ! Add in rounding constant * 2**32,
or %g0, %lo(0x028f4b62), %l0
addcc %o0, %l0, %o0 ! 2**32 * 0.009 999
bcs,a 3f
add %o1, 0x01, %o1
3:
mov HZ, %o0 ! >>32 earlier for wider range
umul %o0, %o1, %o0
rd %y, %o1
ret
restore
EXPORT_SYMBOL(__udelay)
EXPORT_SYMBOL(__ndelay)
/* Handle a software breakpoint */ /* We have to inform parent that child has stopped */
.align 4
.globl breakpoint_trap
breakpoint_trap:
rd %wim,%l3
SAVE_ALL
wr %l0, PSR_ET, %psr
WRITE_PAUSE
st %i0, [%sp + STACKFRAME_SZ + PT_G0] ! for restarting syscalls
call sparc_breakpoint
add %sp, STACKFRAME_SZ, %o0
/* No matter how much overhead this routine has in the worst * case scenario, it is several times better than taking the * traps with the old method of just doing flush_user_windows().
*/
kill_user_windows: ld [%g6 + TI_UWINMASK], %o0 ! get current umask
orcc %g0, %o0, %g0 ! if no bits set, we are done
be 3f ! nothing to do
rd %psr, %o5 ! must clear interrupts
or %o5, PSR_PIL, %o4 ! or else that could change
wr %o4, 0x0, %psr ! the uwinmask state
WRITE_PAUSE ! burn them cycles
1: ld [%g6 + TI_UWINMASK], %o0 ! get consistent state
orcc %g0, %o0, %g0 ! did an interrupt come in?
be 4f ! yep, we are done
rd %wim, %o3 ! get current wim srl %o3, 1, %o4 ! simulate a save
kuw_patch1: sll %o3, 7, %o3 ! compute next wim
or %o4, %o3, %o3 ! result
andncc %o0, %o3, %o0 ! clean this bit in umask
bne kuw_patch1 ! not done yet srl %o3, 1, %o4 ! begin another save simulation
wr %o3, 0x0, %wim ! set the new wim st %g0, [%g6 + TI_UWINMASK] ! clear uwinmask
4:
wr %o5, 0x0, %psr ! re-enable interrupts
WRITE_PAUSE ! burn baby burn
3:
retl ! return st %g0, [%g6 + TI_W_SAVED] ! no windows saved
/* * First deactivate NMI * or we cannot drop ET, cannot get window spill traps. * The busy loop is necessary because the PIO error * sometimes does not go away quickly and we trap again.
*/ sethi %hi(pcic_regs), %o1 ld [%o1 + %lo(pcic_regs)], %o2
! Get pending status for printouts later. ld [%o2 + PCI_SYS_INT_PENDING], %o0
.globl flushw_all
flushw_all:
save %sp, -0x40, %sp
save %sp, -0x40, %sp
save %sp, -0x40, %sp
save %sp, -0x40, %sp
save %sp, -0x40, %sp
save %sp, -0x40, %sp
save %sp, -0x40, %sp
restore
restore
restore
restore
restore
restore
ret
restore
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.