Intel® Quark™ Microcontroller Software Interface  1.4.0
Intel® Quark™ Microcontroller BSP
apic.h
1 /*
2  * {% copyright %}
3  */
4 
5 #ifndef __APIC_H__
6 #define __APIC_H__
7 
8 #include <stdint.h>
9 
10 #include "qm_common.h"
11 #include "qm_soc_regs.h"
12 
13 #define LAPIC_VECTOR_MASK (0xFF)
14 
15 static void _ioapic_set_redtbl_entry(unsigned int irq, uint64_t value)
16 {
17  unsigned int offset = QM_IOAPIC_REG_REDTBL + (irq * 2);
18 
19  QM_IOAPIC->ioregsel.reg = offset;
20  QM_IOAPIC->iowin.reg = value & 0x00000000FFFFFFFF;
21  QM_IOAPIC->ioregsel.reg = offset + 1;
22  QM_IOAPIC->iowin.reg = (value & 0xFFFFFFFF00000000) >> 32;
23 }
24 
25 /* Get redirection table size */
26 static __inline__ int _ioapic_get_redtbl_size(void)
27 {
28  int max_entry_number;
29 
30  QM_IOAPIC->ioregsel.reg = QM_IOAPIC_REG_VER;
31  max_entry_number = (QM_IOAPIC->iowin.reg & 0x00FF0000) >> 16;
32 
33  return max_entry_number + 1;
34 }
35 
36 static uint32_t _ioapic_get_redtbl_entry_lo(unsigned int irq)
37 {
38  QM_IOAPIC->ioregsel.reg = QM_IOAPIC_REG_REDTBL + (irq * 2);
39  return QM_IOAPIC->iowin.reg;
40 }
41 
42 static void _ioapic_set_redtbl_entry_lo(unsigned int irq, uint32_t value)
43 {
44  QM_IOAPIC->ioregsel.reg = QM_IOAPIC_REG_REDTBL + (irq * 2);
45  QM_IOAPIC->iowin.reg = value;
46 }
47 
48 /*
49  * Initialize Local and IOAPIC
50  */
51 static __inline__ void apic_init(void)
52 {
53  int i;
54  int size;
55 
56  /* Enable LAPIC */
57  QM_LAPIC->svr.reg |= BIT(8);
58 
59  /* Set up LVT LINT0 to ExtINT and unmask it */
60  QM_LAPIC->lvtlint0.reg |= (BIT(8) | BIT(9) | BIT(10));
61  QM_LAPIC->lvtlint0.reg &= ~BIT(16);
62 
63  /* Clear up any spurious LAPIC interrupts */
64  QM_LAPIC->eoi.reg = 0;
65 
66  /* Setup IOAPIC Redirection Table */
67  size = _ioapic_get_redtbl_size();
68  for (i = 0; i < size; i++) {
69  _ioapic_set_redtbl_entry(i, BIT(16));
70  }
71 }
72 
73 static __inline__ void ioapic_register_irq(unsigned int irq,
74  unsigned int vector)
75 {
76  uint32_t value;
77 
78  value = _ioapic_get_redtbl_entry_lo(irq);
79 
80  /* Assign vector and set polarity (positive). */
81  value &= ~LAPIC_VECTOR_MASK;
82  value |= (vector & LAPIC_VECTOR_MASK);
83  value &= ~BIT(13);
84 
85  /* Set trigger mode. */
86  switch (irq) {
87  case QM_IRQ_RTC_0_INT:
88  case QM_IRQ_AONPT_0_INT:
89  case QM_IRQ_WDT_0_INT:
90  /* Edge sensitive. */
91  value &= ~BIT(15);
92  break;
93  default:
94  /* Level sensitive. */
95  value |= BIT(15);
96  break;
97  }
98 
99  _ioapic_set_redtbl_entry_lo(irq, value);
100 }
101 
102 static __inline__ void ioapic_mask_irq(unsigned int irq)
103 {
104  uint32_t value = _ioapic_get_redtbl_entry_lo(irq);
105 
106  value |= BIT(16);
107 
108  _ioapic_set_redtbl_entry_lo(irq, value);
109 }
110 
111 static __inline__ void ioapic_unmask_irq(unsigned int irq)
112 {
113  uint32_t value = _ioapic_get_redtbl_entry_lo(irq);
114 
115  value &= ~BIT(16);
116 
117  _ioapic_set_redtbl_entry_lo(irq, value);
118 }
119 
120 #endif /* __APIC_H__ */