netlib.narod.ru< Назад | Оглавление | Далее >

arch/i386/kernel/irq.h

 1666 #ifndef __irq_h
 1667 #define __irq_h
 1668 
 1669 #include <asm/irq.h>
 1670 
 1671 /* Interrupt controller descriptor. This is all we need
 1672  * to describe about the low-level hardware.  */
 1673 struct hw_interrupt_type {
 1674   const char * typename;
 1675   void (*startup)(unsigned int irq);
 1676   void (*shutdown)(unsigned int irq);
 1677   void (*handle)(unsigned int irq,struct pt_regs * regs);
 1678   void (*enable)(unsigned int irq);
 1679   void (*disable)(unsigned int irq);
 1680 };
 1681 
 1682 extern struct hw_interrupt_type no_irq_type;
 1683 
 1684 /* IRQ line status.  */
 1685 #define IRQ_INPROGRESS  1  /* active - do not enter! */
 1686 #define IRQ_DISABLED    2  /* disabled - do not enter! */
 1687 #define IRQ_PENDING     4  /* pending, replay on enable*/
 1688 #define IRQ_REPLAY      8  /* replayed but not acked */
 1689 #define IRQ_AUTODETECT  16 /* IRQ being autodetected */
 1690 
 1691 /* This is the "IRQ descriptor", which contains various
 1692  * information about the irq, including what kind of
 1693  * hardware handling it has, whether it is disabled etc
 1694  * etc.
 1695  *
 1696  * Pad this out to 32 bytes for cache and indexing
 1697  * reasons.  */
 1698 typedef struct {
 1699   /* IRQ status - IRQ_INPROGRESS, IRQ_DISABLED */
 1700   unsigned int status;
 1701   /* handle/enable/disable functions */
 1702   struct hw_interrupt_type *handler;
 1703   /* IRQ action list */
 1704   struct irqaction *action;
 1705   /* Disable depth for nested irq disables */
 1706   unsigned int depth;
 1707 } irq_desc_t;
 1708 
 1709 /* IDT vectors usable for external interrupt sources
 1710  * start at 0x20: */
 1711 #define FIRST_EXTERNAL_VECTOR   0x20
 1712 
 1713 #define SYSCALL_VECTOR          0x80
 1714 
 1715 /* Vectors 0x20-0x2f are used for ISA interrupts. */
 1716 
 1717 /* Special IRQ vectors used by the SMP architecture:
 1718  *
 1719  * (some of the following vectors are 'rare', they might
 1720  * be merged into a single vector to save vector
 1721  * space. TLB, reschedule and local APIC vectors are
 1722  * performance-critical.)  */
 1723 #define RESCHEDULE_VECTOR       0x30
 1724 #define INVALIDATE_TLB_VECTOR   0x31
 1725 #define STOP_CPU_VECTOR         0x40
 1726 #define LOCAL_TIMER_VECTOR      0x41
 1727 #define MTRR_CHANGE_VECTOR      0x50
 1728 
 1729 /* First APIC vector available to drivers: (vectors
 1730  * 0x51-0xfe) */
 1731 #define IRQ0_TRAP_VECTOR        0x51
 1732 
 1733 /* This IRQ should never happen, but we print a message
 1734  nevertheless.  */
 1735 #define SPURIOUS_APIC_VECTOR    0xff
 1736 
 1737 extern irq_desc_t irq_desc[NR_IRQS];
 1738 extern int irq_vector[NR_IRQS];
 1739 #define IO_APIC_VECTOR(irq)     irq_vector[irq]
 1740 
 1741 extern void init_IRQ_SMP(void);
 1742 extern int handle_IRQ_event(unsigned int,
 1743                    struct pt_regs *, struct irqaction *);
 1744 extern int setup_x86_irq(unsigned int,
 1745                          struct irqaction *);
 1746 
 1747 /* Various low-level irq details needed by irq.c,
 1748  * process.c, time.c, io_apic.c and smp.c
 1749  *
 1750  * Interrupt entry/exit code at both C and assembly level
 1751  */
 1752 
 1753 extern void no_action(int cpl, void *dev_id,
 1754                       struct pt_regs *regs);
 1755 extern void mask_irq(unsigned int irq);
 1756 extern void unmask_irq(unsigned int irq);
 1757 extern void disable_8259A_irq(unsigned int irq);
 1758 extern int i8259A_irq_pending(unsigned int irq);
 1759 extern void ack_APIC_irq(void);
 1760 extern void FASTCALL(send_IPI_self(int vector));
 1761 extern void smp_send_mtrr(void);
 1762 extern void init_VISWS_APIC_irqs(void);
 1763 extern void setup_IO_APIC(void);
 1764 extern int IO_APIC_get_PCI_irq_vector(int bus, int slot,
 1765                                       int fn);
 1766 extern void make_8259A_irq(unsigned int irq);
 1767 extern void send_IPI(int dest, int vector);
 1768 extern void init_pic_mode(void);
 1769 extern void print_IO_APIC(void);
 1770 
 1771 extern unsigned long io_apic_irqs;
 1772 
 1773 extern char _stext, _etext;
 1774 
 1775 #define MAX_IRQ_SOURCES 128
 1776 #define MAX_MP_BUSSES 32
 1777 enum mp_bustype {
 1778   MP_BUS_ISA,
 1779   MP_BUS_PCI
 1780 };
 1781 extern int mp_bus_id_to_type [MAX_MP_BUSSES];
 1782 extern int mp_bus_id_to_pci_bus [MAX_MP_BUSSES];
 1783 extern char ioapic_OEM_ID [16];
 1784 extern char ioapic_Product_ID [16];
 1785 
 1786 extern spinlock_t irq_controller_lock;
 1787 
 1788 #ifdef __SMP__
 1789 
 1790 #include <asm/atomic.h>
 1791 
 1792 static inline void irq_enter(int cpu, unsigned int irq)
 1793 {
 Комментарий
 1794   hardirq_enter(cpu);
 1795   while (test_bit(0,&global_irq_lock)) {
 1796     /* nothing */;
 1797   }
 1798 }
 1799 
 1800 static inline void irq_exit(int cpu, unsigned int irq)
 1801 {
 1802   hardirq_exit(cpu);
 1803 }
 1804 
 1805 #define IO_APIC_IRQ(x) (((x) >= 16) ||                  \
 1806                         ((1<<(x)) & io_apic_irqs))
 1807 
 1808 #else
 1809 
 1810 #define irq_enter(cpu, irq)     (++local_irq_count[cpu])
 1811 #define irq_exit(cpu, irq)      (--local_irq_count[cpu])
 1812 
 1813 #define IO_APIC_IRQ(x)  (0)
 1814 
 1815 #endif
 1816 
 1817 #define __STR(x) #x
 1818 #define STR(x) __STR(x)
 1819 
 1820 #define SAVE_ALL                                        \
 1821   "cld\n\t"                                             \
 1822   "pushl %es\n\t"                                       \
 1823   "pushl %ds\n\t"                                       \
 1824   "pushl %eax\n\t"                                      \
 1825   "pushl %ebp\n\t"                                      \
 1826   "pushl %edi\n\t"                                      \
 1827   "pushl %esi\n\t"                                      \
 1828   "pushl %edx\n\t"                                      \
 1829   "pushl %ecx\n\t"                                      \
 1830   "pushl %ebx\n\t"                                      \
 1831   "movl $" STR(__KERNEL_DS) ",%edx\n\t"                 \
 1832   "movl %dx,%ds\n\t"                                    \
 1833   "movl %dx,%es\n\t"
 1834 
 1835 #define IRQ_NAME2(nr) nr##_interrupt(void)
 1836 #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
 1837 
 1838 #define GET_CURRENT                                     \
 1839   "movl %esp, %ebx\n\t"                                 \
 1840   "andl $-8192, %ebx\n\t"
 1841 
 1842 #ifdef __SMP__
 1843 
 1844 /* SMP has a few special interrupts for IPI messages */
 1845 
 1846 #define BUILD_SMP_INTERRUPT(x)                          \
 1847 asmlinkage void x(void);                                \
 1848 __asm__(                                                \
 1849 "\n"__ALIGN_STR"\n"                                     \
 1850 SYMBOL_NAME_STR(x) ":\n\t"                              \
 1851   "pushl $-1\n\t"                                       \
 1852   SAVE_ALL                                              \
 1853   "call "SYMBOL_NAME_STR(smp_##x)"\n\t"                 \
 1854   "jmp ret_from_intr\n");
 1855 
 1856 #define BUILD_SMP_TIMER_INTERRUPT(x)                    \
 1857 asmlinkage void x(struct pt_regs * regs);               \
 1858 __asm__(                                                \
 1859 "\n"__ALIGN_STR"\n"                                     \
 1860 SYMBOL_NAME_STR(x) ":\n\t"                              \
 1861   "pushl $-1\n\t"                                       \
 1862   SAVE_ALL                                              \
 1863   "movl %esp,%eax\n\t"                                  \
 1864   "pushl %eax\n\t"                                      \
 1865   "call "SYMBOL_NAME_STR(smp_##x)"\n\t"                 \
 1866   "addl $4,%esp\n\t"                                    \
 1867   "jmp ret_from_intr\n");
 1868 
 1869 #endif /* __SMP__ */
 1870 
 1871 #define BUILD_COMMON_IRQ()                              \
 1872 __asm__(                                                \
 1873   "\n" __ALIGN_STR"\n"                                  \
 1874   "common_interrupt:\n\t"                               \
 1875   SAVE_ALL                                              \
 1876   "pushl $ret_from_intr\n\t"                            \
 1877   "jmp "SYMBOL_NAME_STR(do_IRQ));
 1878 
 1879 /* subtle. orig_eax is used by the signal code to
 1880  * distinct between system calls and interrupted 'random
 1881  * user-space'. Thus we have to put a negative value into
 1882  * orig_eax here. (the problem is that both system calls
 1883  * and IRQs want to have small integer numbers in
 1884  * orig_eax, and the syscall code has won the
 1885  * optimization conflict ;) */
 1886 #define BUILD_IRQ(nr)                                   \
 1887 asmlinkage void IRQ_NAME(nr);                           \
 1888 __asm__(                                                \
 1889 "\n"__ALIGN_STR"\n"                                     \
 1890 SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t"              \
 1891   "pushl $"#nr"-256\n\t"                                \
 1892   "jmp common_interrupt");
 1893 
 1894 /* x86 profiling function, SMP safe. We might want to do
 1895  * this in assembly totally?  */
 1896 static inline void x86_do_profile (unsigned long eip)
 1897 {
 1898   if (prof_buffer && current->pid) {
 1899     eip -= (unsigned long) &_stext;
 1900     eip >>= prof_shift;
 1901     /* Don't ignore out-of-bounds EIP values silently,
 1902      * put them into the last histogram slot, so if
 1903      * present, they will show up as a sharp peak.  */
 1904     if (eip > prof_len-1)
 1905       eip = prof_len-1;
 1906     atomic_inc((atomic_t *)&prof_buffer[eip]);
 1907   }
 1908 }
 1909 
 1910 #endif

netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz