p7utils/src/p7os/cake.exe/libgint/src/core/gint_vbr.s

67 lines
1.2 KiB
ArmAsm

/*
gint_vbr
Some of the work, especially related to setting and un-setting the vbr
address needs to be done in assembler.
*/
.global _gint_getVBR
.global _gint_setVBR
/*
gint_getVBR()
Returns the current vbr address.
*/
_gint_getVBR:
rts
stc vbr, r0
/*
gint_setVBR()
This is quite the hard part when modifying the vbr. We need to set
immediately the interrupt priorities of our own handler, or restore
the ones used by the system ; otherwise we may receive interrupts
requests that the new handler doesn't handle, which will cause the
whole program to freeze.
Therefore, we must set vbr *and* change interrupt priorities while
having disabled all the interrupts in the status register. That's why
this function takes as parameter the priority management function.
*/
_gint_setVBR:
sts.l pr, @-r15
/* Blocking all interrupts. */
mov.l sr_block, r0
stc sr, r3
or r0, r3
ldc r3, sr
/* Setting the vbr address. */
ldc r4, vbr
/* Calling the priority manager. */
jsr @r5
nop
/* Activating interrupts again. */
mov.l sr_block, r0
not r0, r0
stc sr, r3
and r0, r3
ldc r3, sr
lds.l @r15+, pr
rts
nop
.align 4
sr_block:
.long (1 << 28)