Lines Matching refs:s
42 static void pic_lock(struct kvm_pic *s) in pic_lock() argument
43 __acquires(&s->lock) in pic_lock()
45 spin_lock(&s->lock); in pic_lock()
48 static void pic_unlock(struct kvm_pic *s) in pic_unlock() argument
49 __releases(&s->lock) in pic_unlock()
51 bool wakeup = s->wakeup_needed; in pic_unlock()
55 s->wakeup_needed = false; in pic_unlock()
57 spin_unlock(&s->lock); in pic_unlock()
60 kvm_for_each_vcpu(i, vcpu, s->kvm) { in pic_unlock()
75 static void pic_clear_isr(struct kvm_kpic_state *s, int irq) in pic_clear_isr() argument
77 s->isr &= ~(1 << irq); in pic_clear_isr()
78 if (s != &s->pics_state->pics[0]) in pic_clear_isr()
86 pic_unlock(s->pics_state); in pic_clear_isr()
87 kvm_notify_acked_irq(s->pics_state->kvm, SELECT_PIC(irq), irq); in pic_clear_isr()
88 pic_lock(s->pics_state); in pic_clear_isr()
94 static inline int pic_set_irq1(struct kvm_kpic_state *s, int irq, int level) in pic_set_irq1() argument
98 if (s->elcr & mask) /* level triggered */ in pic_set_irq1()
100 ret = !(s->irr & mask); in pic_set_irq1()
101 s->irr |= mask; in pic_set_irq1()
102 s->last_irr |= mask; in pic_set_irq1()
104 s->irr &= ~mask; in pic_set_irq1()
105 s->last_irr &= ~mask; in pic_set_irq1()
109 if ((s->last_irr & mask) == 0) { in pic_set_irq1()
110 ret = !(s->irr & mask); in pic_set_irq1()
111 s->irr |= mask; in pic_set_irq1()
113 s->last_irr |= mask; in pic_set_irq1()
115 s->last_irr &= ~mask; in pic_set_irq1()
117 return (s->imr & mask) ? -1 : ret; in pic_set_irq1()
124 static inline int get_priority(struct kvm_kpic_state *s, int mask) in get_priority() argument
130 while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0) in get_priority()
138 static int pic_get_irq(struct kvm_kpic_state *s) in pic_get_irq() argument
142 mask = s->irr & ~s->imr; in pic_get_irq()
143 priority = get_priority(s, mask); in pic_get_irq()
151 mask = s->isr; in pic_get_irq()
152 if (s->special_fully_nested_mode && s == &s->pics_state->pics[0]) in pic_get_irq()
154 cur_priority = get_priority(s, mask); in pic_get_irq()
159 return (priority + s->priority_add) & 7; in pic_get_irq()
168 static void pic_update_irq(struct kvm_pic *s) in pic_update_irq() argument
172 irq2 = pic_get_irq(&s->pics[1]); in pic_update_irq()
177 pic_set_irq1(&s->pics[0], 2, 1); in pic_update_irq()
178 pic_set_irq1(&s->pics[0], 2, 0); in pic_update_irq()
180 irq = pic_get_irq(&s->pics[0]); in pic_update_irq()
181 pic_irq_request(s->kvm, irq >= 0); in pic_update_irq()
184 void kvm_pic_update_irq(struct kvm_pic *s) in kvm_pic_update_irq() argument
186 pic_lock(s); in kvm_pic_update_irq()
187 pic_update_irq(s); in kvm_pic_update_irq()
188 pic_unlock(s); in kvm_pic_update_irq()
191 int kvm_pic_set_irq(struct kvm_pic *s, int irq, int irq_source_id, int level) in kvm_pic_set_irq() argument
197 pic_lock(s); in kvm_pic_set_irq()
198 irq_level = __kvm_irq_line_state(&s->irq_states[irq], in kvm_pic_set_irq()
200 ret = pic_set_irq1(&s->pics[irq >> 3], irq & 7, irq_level); in kvm_pic_set_irq()
201 pic_update_irq(s); in kvm_pic_set_irq()
202 trace_kvm_pic_set_irq(irq >> 3, irq & 7, s->pics[irq >> 3].elcr, in kvm_pic_set_irq()
203 s->pics[irq >> 3].imr, ret == 0); in kvm_pic_set_irq()
204 pic_unlock(s); in kvm_pic_set_irq()
209 void kvm_pic_clear_all(struct kvm_pic *s, int irq_source_id) in kvm_pic_clear_all() argument
213 pic_lock(s); in kvm_pic_clear_all()
215 __clear_bit(irq_source_id, &s->irq_states[i]); in kvm_pic_clear_all()
216 pic_unlock(s); in kvm_pic_clear_all()
222 static inline void pic_intack(struct kvm_kpic_state *s, int irq) in pic_intack() argument
224 s->isr |= 1 << irq; in pic_intack()
228 if (!(s->elcr & (1 << irq))) in pic_intack()
229 s->irr &= ~(1 << irq); in pic_intack()
231 if (s->auto_eoi) { in pic_intack()
232 if (s->rotate_on_auto_eoi) in pic_intack()
233 s->priority_add = (irq + 1) & 7; in pic_intack()
234 pic_clear_isr(s, irq); in pic_intack()
242 struct kvm_pic *s = pic_irqchip(kvm); in kvm_pic_read_irq() local
244 s->output = 0; in kvm_pic_read_irq()
246 pic_lock(s); in kvm_pic_read_irq()
247 irq = pic_get_irq(&s->pics[0]); in kvm_pic_read_irq()
249 pic_intack(&s->pics[0], irq); in kvm_pic_read_irq()
251 irq2 = pic_get_irq(&s->pics[1]); in kvm_pic_read_irq()
253 pic_intack(&s->pics[1], irq2); in kvm_pic_read_irq()
259 intno = s->pics[1].irq_base + irq2; in kvm_pic_read_irq()
262 intno = s->pics[0].irq_base + irq; in kvm_pic_read_irq()
268 intno = s->pics[0].irq_base + irq; in kvm_pic_read_irq()
270 pic_update_irq(s); in kvm_pic_read_irq()
271 pic_unlock(s); in kvm_pic_read_irq()
276 void kvm_pic_reset(struct kvm_kpic_state *s) in kvm_pic_reset() argument
280 u8 edge_irr = s->irr & ~s->elcr; in kvm_pic_reset()
283 s->last_irr = 0; in kvm_pic_reset()
284 s->irr &= s->elcr; in kvm_pic_reset()
285 s->imr = 0; in kvm_pic_reset()
286 s->priority_add = 0; in kvm_pic_reset()
287 s->special_mask = 0; in kvm_pic_reset()
288 s->read_reg_select = 0; in kvm_pic_reset()
289 if (!s->init4) { in kvm_pic_reset()
290 s->special_fully_nested_mode = 0; in kvm_pic_reset()
291 s->auto_eoi = 0; in kvm_pic_reset()
293 s->init_state = 1; in kvm_pic_reset()
295 kvm_for_each_vcpu(i, vcpu, s->pics_state->kvm) in kvm_pic_reset()
307 pic_clear_isr(s, irq); in kvm_pic_reset()
312 struct kvm_kpic_state *s = opaque; in pic_ioport_write() local
318 s->init4 = val & 1; in pic_ioport_write()
324 kvm_pic_reset(s); in pic_ioport_write()
327 s->poll = 1; in pic_ioport_write()
329 s->read_reg_select = val & 1; in pic_ioport_write()
331 s->special_mask = (val >> 5) & 1; in pic_ioport_write()
337 s->rotate_on_auto_eoi = cmd >> 2; in pic_ioport_write()
341 priority = get_priority(s, s->isr); in pic_ioport_write()
343 irq = (priority + s->priority_add) & 7; in pic_ioport_write()
345 s->priority_add = (irq + 1) & 7; in pic_ioport_write()
346 pic_clear_isr(s, irq); in pic_ioport_write()
347 pic_update_irq(s->pics_state); in pic_ioport_write()
352 pic_clear_isr(s, irq); in pic_ioport_write()
353 pic_update_irq(s->pics_state); in pic_ioport_write()
356 s->priority_add = (val + 1) & 7; in pic_ioport_write()
357 pic_update_irq(s->pics_state); in pic_ioport_write()
361 s->priority_add = (irq + 1) & 7; in pic_ioport_write()
362 pic_clear_isr(s, irq); in pic_ioport_write()
363 pic_update_irq(s->pics_state); in pic_ioport_write()
370 switch (s->init_state) { in pic_ioport_write()
372 u8 imr_diff = s->imr ^ val, in pic_ioport_write()
373 off = (s == &s->pics_state->pics[0]) ? 0 : 8; in pic_ioport_write()
374 s->imr = val; in pic_ioport_write()
378 s->pics_state->kvm, in pic_ioport_write()
381 !!(s->imr & (1 << irq))); in pic_ioport_write()
382 pic_update_irq(s->pics_state); in pic_ioport_write()
386 s->irq_base = val & 0xf8; in pic_ioport_write()
387 s->init_state = 2; in pic_ioport_write()
390 if (s->init4) in pic_ioport_write()
391 s->init_state = 3; in pic_ioport_write()
393 s->init_state = 0; in pic_ioport_write()
396 s->special_fully_nested_mode = (val >> 4) & 1; in pic_ioport_write()
397 s->auto_eoi = (val >> 1) & 1; in pic_ioport_write()
398 s->init_state = 0; in pic_ioport_write()
403 static u32 pic_poll_read(struct kvm_kpic_state *s, u32 addr1) in pic_poll_read() argument
407 ret = pic_get_irq(s); in pic_poll_read()
410 s->pics_state->pics[0].isr &= ~(1 << 2); in pic_poll_read()
411 s->pics_state->pics[0].irr &= ~(1 << 2); in pic_poll_read()
413 s->irr &= ~(1 << ret); in pic_poll_read()
414 pic_clear_isr(s, ret); in pic_poll_read()
416 pic_update_irq(s->pics_state); in pic_poll_read()
419 pic_update_irq(s->pics_state); in pic_poll_read()
427 struct kvm_kpic_state *s = opaque; in pic_ioport_read() local
433 if (s->poll) { in pic_ioport_read()
434 ret = pic_poll_read(s, addr1); in pic_ioport_read()
435 s->poll = 0; in pic_ioport_read()
438 if (s->read_reg_select) in pic_ioport_read()
439 ret = s->isr; in pic_ioport_read()
441 ret = s->irr; in pic_ioport_read()
443 ret = s->imr; in pic_ioport_read()
449 struct kvm_kpic_state *s = opaque; in elcr_ioport_write() local
450 s->elcr = val & s->elcr_mask; in elcr_ioport_write()
455 struct kvm_kpic_state *s = opaque; in elcr_ioport_read() local
456 return s->elcr; in elcr_ioport_read()
474 static int picdev_write(struct kvm_pic *s, in picdev_write() argument
485 pic_lock(s); in picdev_write()
491 pic_ioport_write(&s->pics[addr >> 7], addr, data); in picdev_write()
495 elcr_ioport_write(&s->pics[addr & 1], addr, data); in picdev_write()
498 pic_unlock(s); in picdev_write()
502 static int picdev_read(struct kvm_pic *s, in picdev_read() argument
513 pic_lock(s); in picdev_read()
519 data = pic_ioport_read(&s->pics[addr >> 7], addr); in picdev_read()
523 data = elcr_ioport_read(&s->pics[addr & 1], addr); in picdev_read()
527 pic_unlock(s); in picdev_read()
578 struct kvm_pic *s = pic_irqchip(kvm); in pic_irq_request() local
580 if (!s->output) in pic_irq_request()
581 s->wakeup_needed = true; in pic_irq_request()
582 s->output = level; in pic_irq_request()
602 struct kvm_pic *s; in kvm_create_pic() local
605 s = kzalloc(sizeof(struct kvm_pic), GFP_KERNEL); in kvm_create_pic()
606 if (!s) in kvm_create_pic()
608 spin_lock_init(&s->lock); in kvm_create_pic()
609 s->kvm = kvm; in kvm_create_pic()
610 s->pics[0].elcr_mask = 0xf8; in kvm_create_pic()
611 s->pics[1].elcr_mask = 0xde; in kvm_create_pic()
612 s->pics[0].pics_state = s; in kvm_create_pic()
613 s->pics[1].pics_state = s; in kvm_create_pic()
618 kvm_iodevice_init(&s->dev_master, &picdev_master_ops); in kvm_create_pic()
619 kvm_iodevice_init(&s->dev_slave, &picdev_slave_ops); in kvm_create_pic()
620 kvm_iodevice_init(&s->dev_eclr, &picdev_eclr_ops); in kvm_create_pic()
623 &s->dev_master); in kvm_create_pic()
627 ret = kvm_io_bus_register_dev(kvm, KVM_PIO_BUS, 0xa0, 2, &s->dev_slave); in kvm_create_pic()
631 ret = kvm_io_bus_register_dev(kvm, KVM_PIO_BUS, 0x4d0, 2, &s->dev_eclr); in kvm_create_pic()
637 return s; in kvm_create_pic()
640 kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &s->dev_slave); in kvm_create_pic()
643 kvm_io_bus_unregister_dev(kvm, KVM_PIO_BUS, &s->dev_master); in kvm_create_pic()
648 kfree(s); in kvm_create_pic()