|
|
1.1 ! root 1: /* ! 2: * Copyright (C) 2007-2009 Free Software Foundation ! 3: * ! 4: * This program is free software ; you can redistribute it and/or modify ! 5: * it under the terms of the GNU General Public License as published by ! 6: * the Free Software Foundation ; either version 2 of the License, or ! 7: * (at your option) any later version. ! 8: * ! 9: * This program is distributed in the hope that it will be useful, ! 10: * but WITHOUT ANY WARRANTY ; without even the implied warranty of ! 11: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 12: * GNU General Public License for more details. ! 13: * ! 14: * You should have received a copy of the GNU General Public License ! 15: * along with the program ; if not, write to the Free Software ! 16: * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ! 17: */ ! 18: ! 19: #include <sys/types.h> ! 20: #include <string.h> ! 21: #include <mach/xen.h> ! 22: #include <machine/xen.h> ! 23: #include <machine/ipl.h> ! 24: #include <machine/gdt.h> ! 25: #include <xen/console.h> ! 26: #include "evt.h" ! 27: ! 28: #define NEVNT (sizeof(unsigned long) * sizeof(unsigned long) * 8) ! 29: int int_mask[NSPL]; ! 30: ! 31: spl_t curr_ipl; ! 32: ! 33: void (*ivect[NEVNT])(); ! 34: int intpri[NEVNT]; ! 35: int iunit[NEVNT]; ! 36: ! 37: void hyp_c_callback(void *ret_addr, void *regs) ! 38: { ! 39: int i, j, n; ! 40: int cpu = 0; ! 41: unsigned long pending_sel; ! 42: ! 43: hyp_shared_info.vcpu_info[cpu].evtchn_upcall_pending = 0; ! 44: /* no need for a barrier on x86, xchg is already one */ ! 45: #if !(defined(__i386__) || defined(__x86_64__)) ! 46: wmb(); ! 47: #endif ! 48: while ((pending_sel = xchgl(&hyp_shared_info.vcpu_info[cpu].evtchn_pending_sel, 0))) { ! 49: ! 50: for (i = 0; pending_sel; i++, pending_sel >>= 1) { ! 51: unsigned long pending; ! 52: ! 53: if (!(pending_sel & 1)) ! 54: continue; ! 55: ! 56: while ((pending = (hyp_shared_info.evtchn_pending[i] & ~hyp_shared_info.evtchn_mask[i]))) { ! 57: ! 58: n = i * sizeof(unsigned long); ! 59: for (j = 0; pending; j++, n++, pending >>= 1) { ! 60: if (!(pending & 1)) ! 61: continue; ! 62: ! 63: if (ivect[n]) { ! 64: spl_t spl = splx(intpri[n]); ! 65: asm ("lock; and %1,%0":"=m"(hyp_shared_info.evtchn_pending[i]):"r"(~(1UL<<j))); ! 66: ivect[n](iunit[n], spl, ret_addr, regs); ! 67: splx_cli(spl); ! 68: } else { ! 69: printf("warning: lost unbound event %d\n", n); ! 70: asm ("lock; and %1,%0":"=m"(hyp_shared_info.evtchn_pending[i]):"r"(~(1UL<<j))); ! 71: } ! 72: } ! 73: } ! 74: } ! 75: } ! 76: } ! 77: ! 78: void form_int_mask(void) ! 79: { ! 80: unsigned int i, j, bit, mask; ! 81: ! 82: for (i=SPL0; i < NSPL; i++) { ! 83: for (j=0x00, bit=0x01, mask = 0; j < NEVNT; j++, bit<<=1) ! 84: if (intpri[j] <= i) ! 85: mask |= bit; ! 86: int_mask[i] = mask; ! 87: } ! 88: } ! 89: ! 90: extern void hyp_callback(void); ! 91: extern void hyp_failsafe_callback(void); ! 92: ! 93: void hyp_intrinit() { ! 94: form_int_mask(); ! 95: curr_ipl = SPLHI; ! 96: hyp_shared_info.evtchn_mask[0] = int_mask[SPLHI]; ! 97: hyp_set_callbacks(KERNEL_CS, hyp_callback, ! 98: KERNEL_CS, hyp_failsafe_callback); ! 99: } ! 100: ! 101: void hyp_evt_handler(evtchn_port_t port, void (*handler)(), int unit, spl_t spl) { ! 102: if (port > NEVNT) ! 103: panic("event channel port %d > %d not supported\n", port, NEVNT); ! 104: intpri[port] = spl; ! 105: iunit[port] = unit; ! 106: form_int_mask(); ! 107: wmb(); ! 108: ivect[port] = handler; ! 109: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.