|
|
1.1 ! root 1: / This file contains assembly-language implementations of processor priority- ! 2: / level manipulation functions that would be in-lined using GCC or typical ! 3: / MS-DOS tools. See "spl.c" for routine documentation. ! 4: ! 5: .unixorder ! 6: .include struct.inc ! 7: .include pl.inc ! 8: ! 9: / Because the DDI/DKI processor-priority manipulation system I have chosen ! 10: / to implement uses interrupt masks, we need access to a reasonable amount ! 11: / of per-CPU global information... ! 12: / ! 13: / The current abstract IPL. ! 14: / The current mask for the 'plbase' abstract IPL. ! 15: / The table of additional masks for abstract IPLs. ! 16: / ! 17: / This implementation is for Coherent, uniprocessor only. To make life easier ! 18: / for this code we have put the relevant parts of the "ddi_cpu_data" structure ! 19: / at the front. Coherent 'as' has no structure facility, so we use .set ! 20: / Wouldn't this be easier if there was a .struct facility that knew about ! 21: / the COFF/ABI structure alignment rules? ! 22: ! 23: / struct defcpu { ! 24: .struct defer ! 25: .member df_tab,ptr ! 26: .member df_read,uchar ! 27: .member df_max,uchar ! 28: .member df_write,uchar ! 29: .member df_rlock,uchar ! 30: .member df_wlock,ptr ! 31: .ends defer ! 32: / }; ! 33: .typedef defer_t,defer ! 34: ! 35: / struct dcdata { ! 36: .struct dcdata ! 37: .member dc_cpu_id,uint ! 38: .member dc_base_mask,ulong ! 39: .member dc_int_level,uchar ! 40: .member dc_user_level,uchar ! 41: .member dc_ipl,uchar ! 42: .member dc_defint,defer_t ! 43: .member dc_defproc,defer_t ! 44: .ends dcdata ! 45: / }; ! 46: .typedef dcdata_t,dcdata ! 47: / struct dgdata { ! 48: / member offsets ! 49: .struct dgdata ! 50: .member dg_defint,defer_t ! 51: .ends dgdata ! 52: / }; ! 53: .typedef dgdata_t,dgdata ! 54: ! 55: cpu .define __ddi_cpu_data ! 56: glob .define __ddi_global_data ! 57: ! 58: .extern cpu,dcdata_t ! 59: .extern glob,dgdata_t ! 60: ! 61: .set PICM,0x21 ! 62: .set SPICM,0xA1 ! 63: ! 64: .globl _masktab / array of longs ! 65: ! 66: .text ! 67: ! 68: .globl splbase ! 69: .globl spltimeout ! 70: .globl spldisk ! 71: .globl splstr ! 72: .globl splhi ! 73: .globl splx ! 74: .globl splraise ! 75: .globl splcmp ! 76: .globl __SET_BASE_MASK ! 77: .globl __CHEAP_DISABLE_INTS ! 78: .globl __CHEAP_ENABLE_INTS ! 79: .globl DDI_BASE_SLAVE_MASK ! 80: .globl DDI_BASE_MASTER_MASK ! 81: ! 82: / pl_t splbase (void) ! 83: splbase: mov $plbase, %ecx ! 84: jmp setnew ! 85: ! 86: spltimeout: mov $pltimeout, %ecx ! 87: jmp setnew ! 88: ! 89: spldisk: mov $pldisk, %ecx ! 90: jmp setnew ! 91: ! 92: splstr: mov $plstr, %ecx ! 93: jmp setnew ! 94: ! 95: splhi: mov $plhi, %ecx ! 96: jmp setnew ! 97: ! 98: / pl_t splx (pl_t _newpl) ! 99: splx: ! 100: movzxb 4(%esp), %ecx / new pl ! 101: setnew: ! 102: movl _masktab(%ecx,4), %eax / new mask ! 103: ! 104: / send the mask out to the PICs after including the base mask info. ! 105: orl cpu+dc_base_mask, %eax ! 106: outb $PICM ! 107: xchgb %ah,%al ! 108: outb $SPICM ! 109: ! 110: / swap the new IPL for the old one, and return the old one. ! 111: movzxb cpu+dc_ipl, %eax ! 112: movb %cl, cpu+dc_ipl ! 113: ! 114: ret ! 115: ! 116: / pl_t splraise (pl_t _newpl) ! 117: splraise: ! 118: movzxb 4(%esp), %ecx / new pl ! 119: ! 120: cmpb cpu+dc_ipl, %cl ! 121: jg setnew ! 122: ! 123: movzxb cpu+dc_ipl, %eax / just return old ! 124: ret ! 125: ! 126: / int splcmp (pl_t l, pl_t r) ! 127: splcmp: movzxb 4(%esp), %eax / left ! 128: sub 4(%esp), %eax / - right ! 129: jz l_eq_r / if eq, %eax == 0 ! 130: / take advantage of 80x86 mov not changing condition codes. ! 131: mov $-1, %eax ! 132: jl l_lt_r / if <, %eax == -1 ! 133: mov $1, %eax / if >, %eax == 1 ! 134: l_eq_r: ! 135: l_lt_r: ! 136: ret ! 137: ! 138: / void __SET_BASE_MASK (intmask_t newmask) ! 139: __SET_BASE_MASK: ! 140: mov 4(%esp), %eax / new mask ! 141: mov %eax, cpu+dc_base_mask / store it ! 142: outb $PICM / mask low ! 143: mov %ah, %al ! 144: outb $SPICM / mask high ! 145: ret ! 146: ! 147: / void __CHEAP_DISABLE_INTS (void) ! 148: __CHEAP_DISABLE_INTS: ! 149: cli ! 150: ret ! 151: ! 152: / void __CHEAP_ENABLE_INTS (void) ! 153: __CHEAP_ENABLE_INTS: ! 154: sti ! 155: ret ! 156: ! 157: / These function should only be called from base level, so that we don't ! 158: / have to iterate over all kinds of junk to work out what the real mask ! 159: / level should be. This condition is trivially satisfied at the moment because ! 160: / these are only called by a Coherent's functions, which aren't protected by ! 161: / any kind of spl... (), just (possibly) an sphi ()/spl (). ! 162: ! 163: / void DDI_BASE_MASTER_MASK (uchar_t mask) ! 164: DDI_BASE_MASTER_MASK: ! 165: mov 4(%esp), %al ! 166: mov %al, cpu+dc_base_mask ! 167: outb $PICM ! 168: ret ! 169: ! 170: / void DDI_BASE_SLAVE_MASK (uchar_t mask) ! 171: DDI_BASE_SLAVE_MASK: ! 172: mov 4(%esp), %al ! 173: mov %al, cpu+dc_base_mask+1 ! 174: outb $SPICM ! 175: ret
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.