github.com/icexin/eggos@v0.4.2-0.20220216025428-78b167e4f349/kernel/trap_thread.go (about) 1 package kernel 2 3 import ( 4 "fmt" 5 "runtime" 6 "syscall" 7 "unsafe" 8 9 "github.com/icexin/eggos/drivers/pic" 10 "github.com/icexin/eggos/kernel/trap" 11 "github.com/icexin/eggos/log" 12 ) 13 14 var ( 15 // 因为中断处理是异步的,在获取一次中断期间可能发生了多次中断, 16 // irqset按位保存发生的中断,对应的中断号为IRQ_BASE+1<<bit 17 irqset uintptr 18 19 traptask threadptr 20 ) 21 22 func runTrapThread() { 23 runtime.LockOSThread() 24 var trapset uintptr 25 var err syscall.Errno 26 const setsize = unsafe.Sizeof(irqset) * 8 27 28 my := Mythread() 29 traptask = (threadptr)(unsafe.Pointer(my)) 30 log.Infof("[trap] tid:%d", my.id) 31 32 for { 33 trapset, _, err = syscall.Syscall(SYS_WAIT_IRQ, 0, 0, 0) 34 if err != 0 { 35 throw("bad SYS_WAIT_IRQ return") 36 } 37 for i := uintptr(0); i < setsize; i++ { 38 if trapset&(1<<i) == 0 { 39 continue 40 } 41 trapno := uintptr(pic.IRQ_BASE + i) 42 43 handler := trap.Handler(int(trapno)) 44 if handler == nil { 45 fmt.Printf("trap handler for %d not found\n", trapno) 46 pic.EOI(trapno) 47 continue 48 } 49 handler() 50 } 51 } 52 } 53 54 //go:nosplit 55 func wakeIRQ(no uintptr) { 56 irqset |= 1 << (no - pic.IRQ_BASE) 57 wakeup(&irqset, 1) 58 Yield() 59 } 60 61 //go:nosplit 62 func waitIRQ() uintptr { 63 if irqset != 0 { 64 ret := irqset 65 irqset = 0 66 return ret 67 } 68 sleepon(&irqset) 69 ret := irqset 70 irqset = 0 71 return ret 72 }