mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
177 lines
6.7 KiB
C
177 lines
6.7 KiB
C
/*
|
|
* Copyright (C) 2014 René Kijewski <rene.kijewski@fu-berlin.de>
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
/**
|
|
* The IRQ handler of x86 boards.
|
|
*
|
|
* @ingroup x86-irq
|
|
* @{
|
|
* @file
|
|
* @author René Kijewski <rene.kijewski@fu-berlin.de>
|
|
*/
|
|
|
|
#ifndef CPU__X86__PIC__H__
|
|
#define CPU__X86__PIC__H__
|
|
|
|
#include <stdint.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* @brief Initialize the Programmable Interrupt Controller.
|
|
*
|
|
* This function is called during initialization by x86_startup().
|
|
* You must not call this function on your own accord.
|
|
*/
|
|
void x86_init_pic(void);
|
|
|
|
#define X86_IRQ_COUNT (0x10) /**< Number of IRQ lines */
|
|
|
|
/**
|
|
* @brief Offset of the IRQ master in the interrupt numbers.
|
|
*
|
|
* x86_interrupts.c expects this value to be `0x20`. Do not change.
|
|
*/
|
|
#define PIC_MASTER_INTERRUPT_BASE (0x20)
|
|
/**
|
|
* @brief Offset of the IRQ slave in the interrupt numbers.
|
|
*
|
|
* The whole IRQ subsystem expects the IRQ slave numbers to come immediately after the master.
|
|
*/
|
|
#define PIC_SLAVE_INTERRUPT_BASE (PIC_MASTER_INTERRUPT_BASE + 8)
|
|
|
|
#define PIC_MASTER (0x20)
|
|
#define PIC_SLAVE (0xA0)
|
|
|
|
#define PIC_COMMAND (0x00)
|
|
#define PIC_DATA (0x01)
|
|
#define PIC_IMR (0x01)
|
|
|
|
#define PIC_EOI 0x20 /**< End-of-interrupt command code */
|
|
|
|
#define PIC_READ_IRR 0x0a /**< OCW3 irq ready next CMD read */
|
|
#define PIC_READ_ISR 0x0b /**< OCW3 irq service next CMD read */
|
|
|
|
#define PIC_ICW1_ICW4 (0x01) /**< ICW4 (not) needed */
|
|
#define PIC_ICW1_SINGLE (0x02) /**< Single (cascade) mode */
|
|
#define PIC_ICW1_INTERVAL4 (0x04) /**< Call address interval 4 (8) */
|
|
#define PIC_ICW1_LEVEL (0x08) /**< Level triggered (edge) mode */
|
|
#define PIC_ICW1_INIT (0x10) /**< Initialization - required! */
|
|
|
|
#define PIC_ICW4_8086 (0x01) /**< 8086/88 (MCS-80/85) mode */
|
|
#define PIC_ICW4_AUTO (0x02) /**< Auto (normal) EOI */
|
|
#define PIC_ICW4_BUF_SLAVE (0x08) /**< Buffered mode/slave */
|
|
#define PIC_ICW4_BUF_MASTER (0x0C) /**< Buffered mode/master */
|
|
#define PIC_ICW4_SFNM (0x10) /**< Special fully nested (not) */
|
|
|
|
#define PIC_NUM_PIT (0x0) /**< IRQ line of the Programmable Interrupt Controller **/
|
|
#define PIC_NUM_KEYBOARD_CONTROLLER_1 (0x1) /**< IRQ line of the first PS/2 port **/
|
|
#define PIC_NUM_SLAVE (0x2) /**< not a valid IRQ line! */
|
|
#define PIC_NUM_RS232_2_4 (0x3) /**< IRQ line of COM 2+4 **/
|
|
#define PIC_NUM_RS232_1_3 (0x4) /**< IRQ line of COM 1+2 **/
|
|
#define PIC_NUM_LPT2 (0x5) /**< IRQ line of the secondary printer or soundcard (available for PCI) **/
|
|
#define PIC_NUM_FLOPPY (0x6) /**< IRQ line of the floppy drive. **/
|
|
#define PIC_NUM_LPT1 (0x7) /**< IRQ line of the parallel port (available for PCI) **/
|
|
|
|
#define PIC_NUM_RTC (0x8) /**< IRQ line of the Real Time Clock **/
|
|
#define PIC_NUM_9 (0x9) /**< Free to use IRQ line (available for PCI) **/
|
|
#define PIC_NUM_ATA_4 (0xa) /**< Free to use IRQ line (available for PCI) **/
|
|
#define PIC_NUM_ATA_3 (0xb) /**< Free to use IRQ line (available for PCI) **/
|
|
#define PIC_NUM_KEYBOARD_CONTROLLER_2 (0xc) /**< IRQ line of the second PS/2 port **/
|
|
#define PIC_NUM_FPU (0xd) /**< not a valid IRQ line! */
|
|
#define PIC_NUM_ATA_1 (0xe) /**< IRQ line of the primary IDE controller **/
|
|
#define PIC_NUM_ATA_2 (0xf) /**< IRQ line of the secondary IDQ controller **/
|
|
|
|
#define PIC_MASK_PIT (1 << PIC_NUM_PIT)
|
|
#define PIC_MASK_KEYBOARD_CONTROLLER_1 (1 << PIC_NUM_KEYBOARD_CONTROLLER_1)
|
|
#define PIC_MASK_SLAVE (1 << PIC_NUM_SLAVE)
|
|
#define PIC_MASK_RS232_2_4 (1 << PIC_NUM_RS232_2_4)
|
|
#define PIC_MASK_RS232_1_3 (1 << PIC_NUM_RS232_1_3)
|
|
#define PIC_MASK_LPT2 (1 << PIC_NUM_LPT2)
|
|
#define PIC_MASK_FLOPPY (1 << PIC_NUM_FLOPPY)
|
|
#define PIC_MASK_LPT1 (1 << PIC_NUM_LPT1)
|
|
|
|
#define PIC_MASK_RTC (1 << PIC_NUM_RTC)
|
|
#define PIC_MASK_9 (1 << PIC_NUM_9)
|
|
#define PIC_MASK_ATA_4 (1 << PIC_NUM_ATA_4)
|
|
#define PIC_MASK_ATA_3 (1 << PIC_NUM_ATA_3)
|
|
#define PIC_MASK_KEYBOARD_CONTROLLER_2 (1 << PIC_NUM_KEYBOARD_CONTROLLER_2)
|
|
#define PIC_MASK_FPU (1 << PIC_NUM_FPU)
|
|
#define PIC_MASK_ATA_1 (1 << PIC_NUM_ATA_1)
|
|
#define PIC_MASK_ATA_2 (1 << PIC_NUM_ATA_2)
|
|
|
|
/**
|
|
* @brief Callback handler if there was an interrupt on this IRQ line.
|
|
* @param irq_num IRQ line in question.
|
|
*
|
|
* This callback is called out of the interrupt handler (inISR() == true).
|
|
* Lengthy operations should be handled in a dedicated thread; use msg_send_int().
|
|
* You must no enable interrupt inside the handler.
|
|
*/
|
|
typedef void (*x86_irq_handler_t)(uint8_t irq_num);
|
|
|
|
/**
|
|
* @brief Set callback function for an IRQ line.
|
|
* @param handler The callback function, or NULL to do nothing.
|
|
*
|
|
* Setting a handler does not enable the interrupt.
|
|
* Use x86_pic_enable_irq() or x86_pic_disable_irq() accordingly.
|
|
*
|
|
* This function must only be called with interrupts disabled.
|
|
*
|
|
* Beware on unsetting interrupt handlers:
|
|
* The PIC default handler will still send an EOI.
|
|
* Especially the keyboard controller does not like it,
|
|
* if it is told that everything was done but it wasn't.
|
|
* A raised #X86_INT_GP might be the least of your problems.
|
|
*/
|
|
void x86_pic_set_handler(unsigned irq, x86_irq_handler_t handler);
|
|
|
|
/**
|
|
* @brief Set the enabled IRQs
|
|
*
|
|
* Beware: this is the exact opposite of masking IRQs.
|
|
*
|
|
* This function should only be called by other subsystems like the PCI subsystem.
|
|
*/
|
|
void x86_pic_set_enabled_irqs(uint16_t mask);
|
|
|
|
/**
|
|
* @brief Enable (unmask) an IRQ
|
|
*
|
|
* This function should only be called by other subsystems like the PCI subsystem.
|
|
*/
|
|
void x86_pic_enable_irq(unsigned num);
|
|
|
|
/**
|
|
* @brief Disable (mask) an IRQ
|
|
*
|
|
* This function should only be called by other subsystems like the PCI subsystem.
|
|
*/
|
|
void x86_pic_disable_irq(unsigned num);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|
|
|
|
/** @} */
|