From b2878db7f7c57ce8be3421520417d3ed09c81ee5 Mon Sep 17 00:00:00 2001 From: patacongo Date: Thu, 10 Mar 2011 22:16:05 +0000 Subject: Restructure interrupt/timer logic git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3362 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/arch/x86/include/i486/arch.h | 262 ++++++++++++++++++++-- nuttx/arch/x86/src/i486/up_irq.c | 359 +++++++++++++++++++++++++++++++ nuttx/arch/x86/src/qemu/Make.defs | 6 +- nuttx/arch/x86/src/qemu/qemu_irq.c | 260 ---------------------- nuttx/arch/x86/src/qemu/qemu_timerisr.c | 30 +-- nuttx/configs/qemu-i486/nsh/defconfig | 2 +- nuttx/configs/qemu-i486/ostest/defconfig | 2 +- 7 files changed, 613 insertions(+), 308 deletions(-) create mode 100755 nuttx/arch/x86/src/i486/up_irq.c delete mode 100755 nuttx/arch/x86/src/qemu/qemu_irq.c (limited to 'nuttx') diff --git a/nuttx/arch/x86/include/i486/arch.h b/nuttx/arch/x86/include/i486/arch.h index 5910f08a1..c5e4adad5 100755 --- a/nuttx/arch/x86/include/i486/arch.h +++ b/nuttx/arch/x86/include/i486/arch.h @@ -55,31 +55,249 @@ /* FLAGS bits */ -#define X86_FLAGS_CF (1 << 0) /* Bit 0: Carry Flag */ - /* Bit 1: Reserved */ -#define X86_FLAGS_PF (1 << 2) /* Bit 2: Parity Flag */ - /* Bit 3: Reserved */ -#define X86_FLAGS_AF (1 << 4) /* Bit 4: Auxillary carry Flag */ - /* Bit 5: Reserved */ -#define X86_FLAGS_ZF (1 << 6) /* Bit 6: Zero Flag */ -#define X86_FLAGS_SF (1 << 7) /* Bit 7: Sign Flag */ -#define X86_FLAGS_TF (1 << 8) /* Bit 8: Trap Flag */ -#define X86_FLAGS_IF (1 << 9) /* Bit 9: Interrupt Flag */ -#define X86_FLAGS_DF (1 << 10) /* Bit 10: Direction Flag */ -#define X86_FLAGS_OF (1 << 11) /* Bit 11: Overflow Flag */ -#define X86_FLAGS_IOPL_SHIFT (12) /* Bits 12-13: IOPL mask (286+ only)*/ -#define X86_FLAGS_IOPL_MASK (3 << X86_FLAGS_IOPL_SHIFT) -#define X86_FLAGS_NT (1 << 14) /* Bit 14: Nested Task */ - /* Bit 15: Reserved */ +#define X86_FLAGS_CF (1 << 0) /* Bit 0: Carry Flag */ + /* Bit 1: Reserved */ +#define X86_FLAGS_PF (1 << 2) /* Bit 2: Parity Flag */ + /* Bit 3: Reserved */ +#define X86_FLAGS_AF (1 << 4) /* Bit 4: Auxillary carry Flag */ + /* Bit 5: Reserved */ +#define X86_FLAGS_ZF (1 << 6) /* Bit 6: Zero Flag */ +#define X86_FLAGS_SF (1 << 7) /* Bit 7: Sign Flag */ +#define X86_FLAGS_TF (1 << 8) /* Bit 8: Trap Flag */ +#define X86_FLAGS_IF (1 << 9) /* Bit 9: Interrupt Flag */ +#define X86_FLAGS_DF (1 << 10) /* Bit 10: Direction Flag */ +#define X86_FLAGS_OF (1 << 11) /* Bit 11: Overflow Flag */ +#define X86_FLAGS_IOPL_SHIFT (12) /* Bits 12-13: IOPL mask (286+ only)*/ +#define X86_FLAGS_IOPL_MASK (3 << X86_FLAGS_IOPL_SHIFT) +#define X86_FLAGS_NT (1 << 14) /* Bit 14: Nested Task */ + /* Bit 15: Reserved */ /* EFLAGS bits (Extend the basic FLAGS bit definitions) */ -#define X86_EFLAGS_RF (1 << 16) /* Bit 16: Resume Flag (386+ only) */ -#define X86_EFLAGS_VM (1 << 17) /* Bit 17: Virtual Mode (386+ only) */ -#define X86_EFLAGS_AC (1 << 18) /* Bit 18: Alignment Check (486SX+ only) */ -#define X86_EFLAGS_VIF (1 << 19) /* Bit 19: Virtual Interrupt Flag (Pentium+) */ -#define X86_EFLAGS_VIP (1 << 20) /* Bit 20: Virtual Interrupt Pending (Pentium+) */ -#define X86_EFLAGS_ID (1 << 21) /* Bit 21: CPUID detection flag (Pentium+) */ +#define X86_EFLAGS_RF (1 << 16) /* Bit 16: Resume Flag (386+ only) */ +#define X86_EFLAGS_VM (1 << 17) /* Bit 17: Virtual Mode (386+ only) */ +#define X86_EFLAGS_AC (1 << 18) /* Bit 18: Alignment Check (486SX+ only) */ +#define X86_EFLAGS_VIF (1 << 19) /* Bit 19: Virtual Interrupt Flag (Pentium+) */ +#define X86_EFLAGS_VIP (1 << 20) /* Bit 20: Virtual Interrupt Pending (Pentium+) */ +#define X86_EFLAGS_ID (1 << 21) /* Bit 21: CPUID detection flag (Pentium+) */ + +/* Programmable Interrupt Controller (PIC) */ + +/* Operational Control Words + * + * The first instruction the Operation Control Word 1 (OCW1) to set which + * IRQ's to mask and which IRQ's not to. + */ + +#define PIC1_OCW1 0x20 +#define PIC2_OCW1 0xa0 + +# define PIC1_OCW1_IRQ0 (1 << 0) /* IRQ0 System Timer */ +# define PIC1_OCW1_IRQ1 (1 << 1) /* IRQ1 Keyboard */ +# define PIC1_OCW1_IRQ2 (1 << 2) /* IRQ2 PIC2 */ +# define PIC1_OCW1_IRQ3 (1 << 3) /* IRQ3 Serial Port */ +# define PIC1_OCW1_IRQ4 (1 << 4) /* IRQ4 Serial Port */ +# define PIC1_OCW1_IRQ5 (1 << 5) /* IRQ5 Reserved/Sound Card */ +# define PIC1_OCW1_IRQ6 (1 << 6) /* IRQ6 Floppy Disk Controller */ +# define PIC1_OCW1_IRQ7 (1 << 7) /* IRQ7 Parallel Port */ +# define PIC1_OCW1_ALL + +# define PIC2_OCW1_IRQ8 (1 << 0) /* IRQ8 Real Time Clock */ +# define PIC2_OCW1_IRQ9 (1 << 1) /* IRQ9 Redirected IRQ2 */ +# define PIC2_OCW1_IRQ10 (1 << 2) /* IRQ10 Reserved */ +# define PIC2_OCW1_IRQ11 (1 << 3) /* IRQ11 Reserved */ +# define PIC2_OCW1_IRQ12 (1 << 4) /* IRQ12 PS/2 Mouse */ +# define PIC2_OCW1_IRQ13 (1 << 5) /* IRQ13 Maths Co-Processor */ +# define PIC2_OCW1_IRQ14 (1 << 6) /* IRQ14 Hard Disk Drive */ +# define PIC2_OCW1_IRQ15 (1 << 7) /* IRQ15 Reserved */ +# define PIC2_OCW1_ALL + +/* Operation Control Word 2 selects how the End of Interrupt (EOI) procedure + * works. The only thing of interest to us in this register is the non- + * specific EOI command, which we must send at the end of our ISR's. + */ + +#define PIC1_OCW2 0x20 +#define PIC2_OCW2 0xa0 + +# define PIC_OCW2_ACT_SHIFT (0) +# define PIC_OCW2_ACT_SHIFT (7 << PIC_OCW2_ACT_SHIFT) +# define PIC1_OCW2_ACT_IRQ0 (0 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 0 */ +# define PIC1_OCW2_ACT_IRQ1 (1 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 1 */ +# define PIC1_OCW2_ACT_IRQ2 (2 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 2 */ +# define PIC1_OCW2_ACT_IRQ3 (3 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 3 */ +# define PIC1_OCW2_ACT_IRQ4 (4 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 4 */ +# define PIC1_OCW2_ACT_IRQ5 (5 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 5 */ +# define PIC1_OCW2_ACT_IRQ6 (6 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 6 */ +# define PIC1_OCW2_ACT_IRQ7 (7 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 7 */ + +# define PIC2_OCW2_ACT_IRQ8 (0 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 8 */ +# define PIC2_OCW2_ACT_IRQ9 (1 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 9 */ +# define PIC2_OCW2_ACT_IRQ10 (2 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 10 */ +# define PIC2_OCW2_ACT_IRQ11 (3 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 11 */ +# define PIC2_OCW2_ACT_IRQ12 (4 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 12 */ +# define PIC2_OCW2_ACT_IRQ13 (5 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 13 */ +# define PIC2_OCW2_ACT_IRQ14 (6 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 14 */ +# define PIC2_OCW2_ACT_IRQ15 (7 << PIC_OCW2_ACT_SHIFT) /* Act on IRQ 15 */ + +# define PIC_OCW2_EOI_SHIFT (5) +# define PIC_OCW2_EOI_SHIFT (7 << PIC_OCW2_EOI_SHIFT) +# define PIC_OCW2_EOI_AUTO (0 << PIC_OCW2_EOI_SHIFT) /* Rotate in Auto EOI Mode (Clear) */ +# define PIC_OCW2_EOI_NONSPEC (1 << PIC_OCW2_EOI_SHIFT) /* Non Specific EOI */ +# define PIC_OCW2_EOI_SPEC (3 << PIC_OCW2_EOI_SHIFT) /* Specific EOI */ +# define PIC_OCW2_EOI_RAUTO (4 << PIC_OCW2_EOI_SHIFT) /* Rotate in Auto EOI Mode (Set) */ +# define PIC_OCW2_EOI_RNSPEC (5 << PIC_OCW2_EOI_SHIFT) /* Rotate on Non-Specific EOI */ +# define PIC_OCW2_EOI_PRIO (6 << PIC_OCW2_EOI_SHIFT) /* Set Priority Command (Use Bits 2:0) */ +# define PIC_OCW2_EOI_RSPEC (7 << PIC_OCW2_EOI_SHIFT) /* Rotate on Specific EOI (Use Bits 2:0) */ + +/* Operation Control Word 3. Bits 0 and 1 bitsenable us to read the status + * of the Interrupt Request Register (IRR) and the In-Service Register (ISR). + * This is done by setting the appropriate bits correctly and reading the + * register at the Base Address. + * + * For example if we wanted to read the In-Service Register (ISR), then we + * would set both bits 1 and 0 to 1. The next read to the base register, + * (0x20 for PIC1 or 0xa0 for PIC2) will return the status of the In-Service + * Register. + */ + +#define PIC1_OCW3 0x20 +#define PIC2_OCW3 0xa0 + +# define PIC_OCW3_PCMD_SHIFT (0) /* Poll command */ +# define PIC_OCW3_PCMD_MASK (3 << PIC_OCW3_PCMD_SHIFT) +# define PIC_OCW3_PCMD_IRR (2 << PIC_OCW3_PCMD_SHIFT) /* Next Read Returns Interrupt Request Register */ +# define PIC_OCW3_PCMD_ISR (3 << PIC_OCW3_PCMD_SHIFT) /* Next Read Returns In-Service Register */ +# define PIC_OCW3_POLLCMD (1 << 2) /* Poll command */ +# define PIC_OCW3_ONE (1 << 3) /* Must be set to 1 */ +# define PIC_OCW3_SM_SHIFT (5) +# define PIC_OCW3_SM_SHIFT (3 << PIC_OCW3_SM_SHIFT) +# define PIC_OCW3_RSM (2 << PIC_OCW3_SM_SHIFT) /* Reset Special Mask */ +# define PIC_OCW3_SSM (3 << PIC_OCW3_SM_SHIFT) /* Set Special Mask */ + +/* If the PIC has been reset, it must be initialized with 2 to 4 Initialization + * Command Words (ICW) before it will accept and process Interrupt Requests. The + * following outlines the four possible Initialization Command Words. + */ + +#define PIC1_ICW1 0x20 +#define PIC2_ICW1 0xa0 + +# define PIC_ICW1_ICW4 (1 << 0) /* Will be Sending ICW4 (no ICW4) */ +# define PIC_ICW1_SINGLE (1 << 1) /* Single PIC (vs. Cascaded pics) */ +# define PIC_ICW1_INTERVAL (1 << 2) /* Call Address Interval of 4 (vs 8) */ +# define PIC_ICW1_LEVEL (1 << 3) /* Level Triggered Interrupts (vs Edge) */ +# define PIC_ICW1_ICW1 (1 << 4) /* Must be set to 1 for ICW1 */ +# define PIC_ICW1_VEC_SHIFT (5) /* Interrupt Vector Addresses for MCS-80/85 Mode */ +# define PIC_ICW1_VEC_MASK (7 << PIC_ICW1_VEC_SHIFT) + +/* Initialization Command Word 2 (ICW2) selects which vector information is + * released onto the bus, during the 2nd INTA Pulse. Using the 8086 mode, + * only bits 7:3 need to be used. This will be 00001000 (0x08) for PIC1 and + * 01110000 (0x70) for PIC2. If you wish to relocate the IRQ Vector Table, + * then you can use this register. + */ + +#define PIC1_ICW2 0x21 +#define PIC2_ICW2 0xa1 + +/* There are two different Initialization Command Word 3's. One is used, if + * the PIC is a master, while the other is used for slaves. + */ + +#define PIC1_ICW3 0x21 +#define PIC2_ICW3 0xa1 + +/* Master ICW3 */ + +# define PIC1_ICW3_IRQ0 (1 << 0) /* IRQ0 is connected to a Slave */ +# define PIC1_ICW3_IRQ1 (1 << 1) /* IRQ1 is connected to a Slave */ +# define PIC1_ICW3_IRQ2 (1 << 2) /* IRQ2 is connected to a Slave */ +# define PIC1_ICW3_IRQ3 (1 << 3) /* IRQ3 is connected to a Slave */ +# define PIC1_ICW3_IRQ4 (1 << 4) /* IRQ4 is connected to a Slave */ +# define PIC1_ICW3_IRQ5 (1 << 5) /* IRQ5 is connected to a Slave */ +# define PIC1_ICW3_IRQ6 (1 << 6) /* IRQ6 is connected to a Slave */ +# define PIC1_ICW3_IRQ7 (1 << 7) /* IRQ7 is connected to a Slave */ + +/* And for the slave device, the ICW3 below is used. */ + +# define PIC_ICW3_SID_MASK (0) /* Slave ID */ +# define PIC_ICW3_SID_SHIFT (7 << PIC_ICW3_SID_MASK) +# define PIC_ICW3_SID0 (0 << PIC_ICW3_SID_MASK) /* Slave 0 */ +# define PIC_ICW3_SID1 (1 << PIC_ICW3_SID_MASK) /* Slave 1 */ +# define PIC_ICW3_SID2 (2 << PIC_ICW3_SID_MASK) /* Slave 2 */ +# define PIC_ICW3_SID3 (3 << PIC_ICW3_SID_MASK) /* Slave 3 */ +# define PIC_ICW3_SID4 (4 << PIC_ICW3_SID_MASK) /* Slave 4 */ +# define PIC_ICW3_SID5 (5 << PIC_ICW3_SID_MASK) /* Slave 5 */ +# define PIC_ICW3_SID6 (6 << PIC_ICW3_SID_MASK) /* Slave 6 */ +# define PIC_ICW3_SID7 (7 << PIC_ICW3_SID_MASK) /* Slave 7 */ + +#define PIC1_ICW4 0x21 +#define PIC2_ICW4 0xa1 + +# define PIC_ICW4_FNM (1 << 4) /* Special Fully Nested Mode */ +# define PIC_ICW4_BMODE_SHIFT (2) /* Bufferd mode */ +# define PIC_ICW4_BMODE_MASK (3 << PIC_ICW4_BMODE_SHIFT) +# define PIC_ICW4_BMODE_NON (0 << PIC_ICW4_BMODE_SHIFT) /* Non - Buffered Mode */ +# define PIC_ICW4_BMODE_SLAVE (2 << PIC_ICW4_BMODE_SHIFT) /* Buffered Mode - Slave */ +# define PIC_ICW4_BMODE_MSTR (3 << PIC_ICW4_BMODE_SHIFT) /* Buffered Mode - Master */ +# define PIC_ICW4_AEOI (1 << 1) /* Auto EOI */ +# define PIC_ICW4_808xMODE (1 << 0) /* 8086/8080 Mode (vs MCS-80/85) */ + +/* Interrupt Mask Register */ + +#define PIC1_IMR 0x21 +#define PIC2_IMR 0xa1 + +# define PIC1_IMR_IRQ0 (1 << 0) /* IRQ0 System Timer */ +# define PIC1_IMR_IRQ1 (1 << 1) /* IRQ1 Keyboard */ +# define PIC1_IMR_IRQ2 (1 << 2) /* IRQ2 PIC2 */ +# define PIC1_IMR_IRQ3 (1 << 3) /* IRQ3 Serial Port */ +# define PIC1_IMR_IRQ4 (1 << 4) /* IRQ4 Serial Port */ +# define PIC1_IMR_IRQ5 (1 << 5) /* IRQ5 Reserved/Sound Card */ +# define PIC1_IMR_IRQ6 (1 << 6) /* IRQ6 Floppy Disk Controller */ +# define PIC1_IMR_IRQ7 (1 << 7) /* IRQ7 Parallel Port */ +# define PIC1_IMR_ALL 0xff + +# define PIC2_IMR_IRQ8 (1 << 0) /* IRQ8 Real Time Clock */ +# define PIC2_IMR_IRQ9 (1 << 1) /* IRQ9 Redirected IRQ2 */ +# define PIC2_IMR_IRQ10 (1 << 2) /* IRQ10 Reserved */ +# define PIC2_IMR_IRQ11 (1 << 3) /* IRQ11 Reserved */ +# define PIC2_IMR_IRQ12 (1 << 4) /* IRQ12 PS/2 Mouse */ +# define PIC2_IMR_IRQ13 (1 << 5) /* IRQ13 Maths Co-Processor */ +# define PIC2_IMR_IRQ14 (1 << 6) /* IRQ14 Hard Disk Drive */ +# define PIC2_IMR_IRQ15 (1 << 7) /* IRQ15 Reserved */ +# define PIC2_IMR_ALL 0xff + +/* Programmable Interrupt Timer Definitions */ + +#define PIT_REG_COUNTER0 0x40 +#define PIT_REG_COUNTER1 0x41 +#define PIT_REG_COUNTER2 0x42 +#define PIT_REG_COMMAND 0x43 + +/* PIT command bit defintions */ + +# define PIT_OCW_BINCOUNT_BCD (1 << 0) /* vs binary */ +# define PIT_OCW_MODE_SHIFT (1) +# define PIT_OCW_MODE_MASK (7 << PIT_OCW_MODE_SHIFT) +# define PIT_OCW_MODE_TMCNT (0 << PIT_OCW_MODE_SHIFT) /* Terminal count */ +# define PIT_OCW_MODE_ONESHOT (1 << PIT_OCW_MODE_SHIFT) /* One shot */ +# define PIT_OCW_MODE_RATEGEN (2 << PIT_OCW_MODE_SHIFT) /* Rate gen */ +# define PIT_OCW_MODE_SQUARE (3 << PIT_OCW_MODE_SHIFT) /* Square wave generation */ +# define PIT_OCW_MODE_SWTRIG (4 << PIT_OCW_MODE_SHIFT) /* Software trigger */ +# define PIT_OCW_MODE_HWTRIG (5 << PIT_OCW_MODE_SHIFT) /* Hardware trigger */ +# define PIT_OCW_RL_SHIFT (4) +# define PIT_OCW_RL_MASK (3 << PIT_OCW_RL_SHIFT) +# define PIT_OCW_RL_LATCH (0 << PIT_OCW_RL_SHIFT) +# define PIT_OCW_RL_LSBONLY (1 << PIT_OCW_RL_SHIFT) +# define PIT_OCW_RL_MSBONLY (2 << PIT_OCW_RL_SHIFT) +# define PIT_OCW_RL_DATA (3 << PIT_OCW_RL_SHIFT) +# define PIT_OCW_COUNTER_SHIFT (6) +# define PIT_OCW_COUNTER_MASK (3 << PIT_OCW_COUNTER_SHIFT) +# define PIT_OCW_COUNTER_0 (0 << PIT_OCW_COUNTER_SHIFT) +# define PIT_OCW_COUNTER_1 (1 << PIT_OCW_COUNTER_SHIFT) +# define PIT_OCW_COUNTER_2 (2 << PIT_OCW_COUNTER_SHIFT) /**************************************************************************** * Public Types diff --git a/nuttx/arch/x86/src/i486/up_irq.c b/nuttx/arch/x86/src/i486/up_irq.c new file mode 100755 index 000000000..33a9130d5 --- /dev/null +++ b/nuttx/arch/x86/src/i486/up_irq.c @@ -0,0 +1,359 @@ +/**************************************************************************** + * arch/x86/src/i486/up_irq.c + * arch/x86/src/chip/up_irq.c + * + * Copyright (C) 2011 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "up_arch.h" +#include "os_internal.h" +#include "up_internal.h" +#include "qemu_internal.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static void idt_outb(uint8_t val, uint16_t addr) __attribute__((noinline)); +static void up_remappic(void); +static void up_idtentry(struct idt_entry_s *entry, uint32_t base, + uint16_t sel, uint8_t flags); +static inline void up_idtinit(void); + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +uint32_t *current_regs; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct idt_entry_s idt_entries[256]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name idt_outb + * + * Description: + * A slightly slower version of outb + * + ****************************************************************************/ + +static void idt_outb(uint8_t val, uint16_t addr) +{ + outb(val, addr); +} + +/**************************************************************************** + * Name up_remappic + * + * Description: + * Remap the PIC. The Programmable Interrupt Controller (PIC) is used to + * combine several sources of interrupt onto one or more CPU lines, while + * allowing priority levels to be assigned to its interrupt outputs. When + * the device has multiple interrupt outputs to assert, it will assert them + * in the order of their relative priority. + * + ****************************************************************************/ + +static void up_remappic(void) +{ + /* Mask interrupts from PIC */ + + idt_outb(PIC1_IMR_ALL, PIC1_IMR); + idt_outb(PIC2_IMR_ALL, PIC2_IMR); + + /* If the PIC has been reset, it must be initialized with 2 to 4 Initialization + * Command Words (ICW) before it will accept and process Interrupt Requests. The + * following outlines the four possible Initialization Command Words. + */ + + /* Remap the irq table for primary: + * + * ICW1 - We will be sending ICW4 + * ICW2 - Address + * ICW3 */ + + idt_outb(PIC_ICW1_ICW4|PIC_ICW1_ICW1, PIC1_ICW1); + idt_outb(0x20, PIC1_ICW2); + idt_outb(PIC1_ICW3_IRQ2, PIC1_ICW3); + idt_outb(PIC_ICW4_808xMODE, PIC1_ICW4); + + /* Remap irq for slave */ + + idt_outb(PIC_ICW1_ICW4|PIC_ICW1_ICW1, PIC2_ICW1); + idt_outb(0x28, PIC2_ICW2); + idt_outb(PIC_ICW3_SID2, PIC2_ICW3); + idt_outb(PIC_ICW4_808xMODE, PIC2_ICW4); +} + +/**************************************************************************** + * Name up_idtentry + * + * Description: + * Initialize one IDT entry. + * + ****************************************************************************/ + +static void up_idtentry(struct idt_entry_s *entry, uint32_t base, + uint16_t sel, uint8_t flags) +{ + entry->lobase = base & 0xffff; + entry->hibase = (base >> 16) & 0xffff; + + entry->sel = sel; + entry->zero = 0; + + /* We must uncomment the OR below when we get to using user-mode. It sets the + * interrupt gate's privilege level to 3. + */ + + entry->flags = flags /* | 0x60 */; +} + +/**************************************************************************** + * Name up_idtinit + * + * Description: + * Initialize the IDT. The Interrupt Descriptor Table (IDT) is a data + * structure used by the x86 architecture to implement an interrupt vector + * table. The IDT is used by the processor to determine the correct + * response to interrupts and exceptions. + * + ****************************************************************************/ + +static inline void up_idtinit(void) +{ + struct idt_ptr_s idt_ptr; + + idt_ptr.limit = sizeof(struct idt_entry_s) * 256 - 1; + idt_ptr.base = (uint32_t)&idt_entries; + + memset(&idt_entries, 0, sizeof(struct idt_entry_s)*256); + + up_remappic(); + + up_idtentry(&idt_entries[0], (uint32_t)vector_isr0 , 0x08, 0x8e); + up_idtentry(&idt_entries[1], (uint32_t)vector_isr1 , 0x08, 0x8e); + up_idtentry(&idt_entries[2], (uint32_t)vector_isr2 , 0x08, 0x8e); + up_idtentry(&idt_entries[3], (uint32_t)vector_isr3 , 0x08, 0x8e); + up_idtentry(&idt_entries[4], (uint32_t)vector_isr4 , 0x08, 0x8e); + up_idtentry(&idt_entries[5], (uint32_t)vector_isr5 , 0x08, 0x8e); + up_idtentry(&idt_entries[6], (uint32_t)vector_isr6 , 0x08, 0x8e); + up_idtentry(&idt_entries[7], (uint32_t)vector_isr7 , 0x08, 0x8e); + up_idtentry(&idt_entries[8], (uint32_t)vector_isr8 , 0x08, 0x8e); + up_idtentry(&idt_entries[9], (uint32_t)vector_isr9 , 0x08, 0x8e); + up_idtentry(&idt_entries[10], (uint32_t)vector_isr10, 0x08, 0x8e); + up_idtentry(&idt_entries[11], (uint32_t)vector_isr11, 0x08, 0x8e); + up_idtentry(&idt_entries[12], (uint32_t)vector_isr12, 0x08, 0x8e); + up_idtentry(&idt_entries[13], (uint32_t)vector_isr13, 0x08, 0x8e); + up_idtentry(&idt_entries[14], (uint32_t)vector_isr14, 0x08, 0x8e); + up_idtentry(&idt_entries[15], (uint32_t)vector_isr15, 0x08, 0x8e); + up_idtentry(&idt_entries[16], (uint32_t)vector_isr16, 0x08, 0x8e); + up_idtentry(&idt_entries[17], (uint32_t)vector_isr17, 0x08, 0x8e); + up_idtentry(&idt_entries[18], (uint32_t)vector_isr18, 0x08, 0x8e); + up_idtentry(&idt_entries[19], (uint32_t)vector_isr19, 0x08, 0x8e); + up_idtentry(&idt_entries[20], (uint32_t)vector_isr20, 0x08, 0x8e); + up_idtentry(&idt_entries[21], (uint32_t)vector_isr21, 0x08, 0x8e); + up_idtentry(&idt_entries[22], (uint32_t)vector_isr22, 0x08, 0x8e); + up_idtentry(&idt_entries[23], (uint32_t)vector_isr23, 0x08, 0x8e); + up_idtentry(&idt_entries[24], (uint32_t)vector_isr24, 0x08, 0x8e); + up_idtentry(&idt_entries[25], (uint32_t)vector_isr25, 0x08, 0x8e); + up_idtentry(&idt_entries[26], (uint32_t)vector_isr26, 0x08, 0x8e); + up_idtentry(&idt_entries[27], (uint32_t)vector_isr27, 0x08, 0x8e); + up_idtentry(&idt_entries[28], (uint32_t)vector_isr28, 0x08, 0x8e); + up_idtentry(&idt_entries[29], (uint32_t)vector_isr29, 0x08, 0x8e); + up_idtentry(&idt_entries[30], (uint32_t)vector_isr30, 0x08, 0x8e); + up_idtentry(&idt_entries[31], (uint32_t)vector_isr31, 0x08, 0x8e); + up_idtentry(&idt_entries[32], (uint32_t)vector_irq0, 0x08, 0x8e); + up_idtentry(&idt_entries[33], (uint32_t)vector_irq1, 0x08, 0x8e); + up_idtentry(&idt_entries[34], (uint32_t)vector_irq2, 0x08, 0x8e); + up_idtentry(&idt_entries[35], (uint32_t)vector_irq3, 0x08, 0x8e); + up_idtentry(&idt_entries[36], (uint32_t)vector_irq4, 0x08, 0x8e); + up_idtentry(&idt_entries[37], (uint32_t)vector_irq5, 0x08, 0x8e); + up_idtentry(&idt_entries[38], (uint32_t)vector_irq6, 0x08, 0x8e); + up_idtentry(&idt_entries[39], (uint32_t)vector_irq7, 0x08, 0x8e); + up_idtentry(&idt_entries[40], (uint32_t)vector_irq8, 0x08, 0x8e); + up_idtentry(&idt_entries[41], (uint32_t)vector_irq9, 0x08, 0x8e); + up_idtentry(&idt_entries[42], (uint32_t)vector_irq10, 0x08, 0x8e); + up_idtentry(&idt_entries[43], (uint32_t)vector_irq11, 0x08, 0x8e); + up_idtentry(&idt_entries[44], (uint32_t)vector_irq12, 0x08, 0x8e); + up_idtentry(&idt_entries[45], (uint32_t)vector_irq13, 0x08, 0x8e); + up_idtentry(&idt_entries[46], (uint32_t)vector_irq14, 0x08, 0x8e); + up_idtentry(&idt_entries[47], (uint32_t)vector_irq15, 0x08, 0x8e); + + idt_flush((uint32_t)&idt_ptr); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + /* currents_regs is non-NULL only while processing an interrupt */ + + current_regs = NULL; + + /* Initialize the IDT */ + + up_idtinit(); + + /* And finally, enable interrupts */ + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + irqrestore(X86_FLAGS_IF); +#endif +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_disable_irq(int irq) +{ + unsigned int regaddr; + uint8_t regbit; + + if ((unsigned)irq >= IRQ0) + { + /* Map the IRQ IMR regiser to a PIC and a bit number */ + + if ((unsigned)irq <= IRQ7) + { + regaddr = PIC1_IMR; + regbit = (1 << (irq - IRQ0)); + } + else if ((unsigned)irq <= IRQ15) + { + regaddr = PIC2_IMR; + regbit = (1 << (irq - IRQ8)); + } + else + { + return; + } + + /* Disable the interrupt */ + + modifyreg8(regaddr, regbit, 0); + } +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the IRQ specified by 'irq' + * + ****************************************************************************/ + +void up_enable_irq(int irq) +{ + unsigned int regaddr; + uint8_t regbit; + + if ((unsigned)irq >= IRQ0) + { + /* Map the IRQ IMR regiser to a PIC and a bit number */ + + if ((unsigned)irq <= IRQ7) + { + regaddr = PIC1_IMR; + regbit = (1 << (irq - IRQ0)); + } + else if ((unsigned)irq <= IRQ15) + { + regaddr = PIC2_IMR; + regbit = (1 << (irq - IRQ8)); + } + else + { + return; + } + + /* Enable the interrupt */ + + modifyreg8(regaddr, 0, regbit); + } +} + +/**************************************************************************** + * Name: up_prioritize_irq + * + * Description: + * Set the priority of an IRQ. + * + * Since this API is not supported on all architectures, it should be + * avoided in common implementations where possible. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_IRQPRIO +int up_prioritize_irq(int irq, int priority) +{ +#warning "Missing Logic" + return OK; +} +#endif diff --git a/nuttx/arch/x86/src/qemu/Make.defs b/nuttx/arch/x86/src/qemu/Make.defs index 4c3a83380..3177f3db4 100755 --- a/nuttx/arch/x86/src/qemu/Make.defs +++ b/nuttx/arch/x86/src/qemu/Make.defs @@ -42,7 +42,7 @@ HEAD_ASRC = qemu_head.S CMN_ASRCS = i486_utils.S CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c \ up_createstack.c up_mdelay.c up_udelay.c up_exit.c\ - up_initialize.c up_initialstate.c up_interruptcontext.c \ + up_initialize.c up_initialstate.c up_interruptcontext.c up_irq.c \ up_modifyreg8.c up_modifyreg16.c up_modifyreg32.c up_regdump.c \ up_releasepending.c up_releasestack.c up_reprioritizertr.c \ up_sigdeliver.c up_schedulesigaction.c up_unblocktask.c \ @@ -51,7 +51,7 @@ CMN_CSRCS = up_allocateheap.c up_assert.c up_blocktask.c up_copystate.c \ # Required QEMU files CHIP_ASRCS = qemu_saveusercontext.S qemu_fullcontextrestore.S qemu_vectors.S -CHIP_CSRCS = qemu_handlers.c qemu_idle.c qemu_irq.c qemu_lowputc.c \ - qemu_lowsetup.c qemu_serial.c qemu_timerisr.c +CHIP_CSRCS = qemu_handlers.c qemu_idle.c qemu_lowputc.c qemu_lowsetup.c \ + qemu_serial.c qemu_timerisr.c # Configuration-dependent QEMU files diff --git a/nuttx/arch/x86/src/qemu/qemu_irq.c b/nuttx/arch/x86/src/qemu/qemu_irq.c deleted file mode 100755 index b92db7882..000000000 --- a/nuttx/arch/x86/src/qemu/qemu_irq.c +++ /dev/null @@ -1,260 +0,0 @@ -/**************************************************************************** - * arch/x86/src/qemu/qemu_irq.c - * arch/x86/src/chip/qemu_irq.c - * - * Copyright (C) 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may be - * used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include "up_arch.h" -#include "os_internal.h" -#include "up_internal.h" -#include "qemu_internal.h" - -/**************************************************************************** - * Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -static void idt_outb(uint8_t val, uint16_t addr) __attribute__((noinline)); -static void up_remappic(void); -static void up_idtentry(struct idt_entry_s *entry, uint32_t base, - uint16_t sel, uint8_t flags); -static inline void up_idtinit(void); - -/**************************************************************************** - * Public Data - ****************************************************************************/ - -uint32_t *current_regs; - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -static struct idt_entry_s idt_entries[256]; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name idt_outb - * - * Description: - * A slightly slower version of outb - * - ****************************************************************************/ - -static void idt_outb(uint8_t val, uint16_t addr) -{ - outb(val, addr); -} - -/**************************************************************************** - * Name up_remappic - * - * Description: - * Remap the PIC. The Programmable Interrupt Controller (PIC) is used to - * combine several sources of interrupt onto one or more CPU lines, while - * allowing priority levels to be assigned to its interrupt outputs. When - * the device has multiple interrupt outputs to assert, it will assert them - * in the order of their relative priority. - * - ****************************************************************************/ - -static void up_remappic(void) -{ - /* Mask interrupts from PIC */ - - idt_outb(0xff, 0x21); - idt_outb(0xff, 0xA1); - - /* Remap the irq table for primary */ - - idt_outb(0x11, 0x20); - idt_outb(0x20, 0x21); - idt_outb(0x04, 0x21); - idt_outb(0x01, 0x21); - - /* Remap irq for slave */ - - idt_outb(0x11, 0xA0); - idt_outb(0x28, 0xA1); - idt_outb(0x02, 0xA1); - idt_outb(0x01, 0xA1); - - /* Enable IRQ0 on the master with the mask */ - - idt_outb( 0xff, 0xA1); - idt_outb( 0xfe, 0x21); -} - -/**************************************************************************** - * Name up_idtentry - * - * Description: - * Initialize one IDT entry. - * - ****************************************************************************/ - -static void up_idtentry(struct idt_entry_s *entry, uint32_t base, - uint16_t sel, uint8_t flags) -{ - entry->lobase = base & 0xFFFF; - entry->hibase = (base >> 16) & 0xFFFF; - - entry->sel = sel; - entry->zero = 0; - - /* We must uncomment the OR below when we get to using user-mode. It sets the - * interrupt gate's privilege level to 3. - */ - - entry->flags = flags /* | 0x60 */; -} - -/**************************************************************************** - * Name up_idtinit - * - * Description: - * Initialize the IDT. The Interrupt Descriptor Table (IDT) is a data - * structure used by the x86 architecture to implement an interrupt vector - * table. The IDT is used by the processor to determine the correct - * response to interrupts and exceptions. - * - ****************************************************************************/ - -static inline void up_idtinit(void) -{ - struct idt_ptr_s idt_ptr; - - idt_ptr.limit = sizeof(struct idt_entry_s) * 256 - 1; - idt_ptr.base = (uint32_t)&idt_entries; - - memset(&idt_entries, 0, sizeof(struct idt_entry_s)*256); - - up_remappic(); - - up_idtentry(&idt_entries[0], (uint32_t)vector_isr0 , 0x08, 0x8e); - up_idtentry(&idt_entries[1], (uint32_t)vector_isr1 , 0x08, 0x8e); - up_idtentry(&idt_entries[2], (uint32_t)vector_isr2 , 0x08, 0x8e); - up_idtentry(&idt_entries[3], (uint32_t)vector_isr3 , 0x08, 0x8e); - up_idtentry(&idt_entries[4], (uint32_t)vector_isr4 , 0x08, 0x8e); - up_idtentry(&idt_entries[5], (uint32_t)vector_isr5 , 0x08, 0x8e); - up_idtentry(&idt_entries[6], (uint32_t)vector_isr6 , 0x08, 0x8e); - up_idtentry(&idt_entries[7], (uint32_t)vector_isr7 , 0x08, 0x8e); - up_idtentry(&idt_entries[8], (uint32_t)vector_isr8 , 0x08, 0x8e); - up_idtentry(&idt_entries[9], (uint32_t)vector_isr9 , 0x08, 0x8e); - up_idtentry(&idt_entries[10], (uint32_t)vector_isr10, 0x08, 0x8e); - up_idtentry(&idt_entries[11], (uint32_t)vector_isr11, 0x08, 0x8e); - up_idtentry(&idt_entries[12], (uint32_t)vector_isr12, 0x08, 0x8e); - up_idtentry(&idt_entries[13], (uint32_t)vector_isr13, 0x08, 0x8e); - up_idtentry(&idt_entries[14], (uint32_t)vector_isr14, 0x08, 0x8e); - up_idtentry(&idt_entries[15], (uint32_t)vector_isr15, 0x08, 0x8e); - up_idtentry(&idt_entries[16], (uint32_t)vector_isr16, 0x08, 0x8e); - up_idtentry(&idt_entries[17], (uint32_t)vector_isr17, 0x08, 0x8e); - up_idtentry(&idt_entries[18], (uint32_t)vector_isr18, 0x08, 0x8e); - up_idtentry(&idt_entries[19], (uint32_t)vector_isr19, 0x08, 0x8e); - up_idtentry(&idt_entries[20], (uint32_t)vector_isr20, 0x08, 0x8e); - up_idtentry(&idt_entries[21], (uint32_t)vector_isr21, 0x08, 0x8e); - up_idtentry(&idt_entries[22], (uint32_t)vector_isr22, 0x08, 0x8e); - up_idtentry(&idt_entries[23], (uint32_t)vector_isr23, 0x08, 0x8e); - up_idtentry(&idt_entries[24], (uint32_t)vector_isr24, 0x08, 0x8e); - up_idtentry(&idt_entries[25], (uint32_t)vector_isr25, 0x08, 0x8e); - up_idtentry(&idt_entries[26], (uint32_t)vector_isr26, 0x08, 0x8e); - up_idtentry(&idt_entries[27], (uint32_t)vector_isr27, 0x08, 0x8e); - up_idtentry(&idt_entries[28], (uint32_t)vector_isr28, 0x08, 0x8e); - up_idtentry(&idt_entries[29], (uint32_t)vector_isr29, 0x08, 0x8e); - up_idtentry(&idt_entries[30], (uint32_t)vector_isr30, 0x08, 0x8e); - up_idtentry(&idt_entries[31], (uint32_t)vector_isr31, 0x08, 0x8e); - up_idtentry(&idt_entries[32], (uint32_t)vector_irq0, 0x08, 0x8e); - up_idtentry(&idt_entries[33], (uint32_t)vector_irq1, 0x08, 0x8e); - up_idtentry(&idt_entries[34], (uint32_t)vector_irq2, 0x08, 0x8e); - up_idtentry(&idt_entries[35], (uint32_t)vector_irq3, 0x08, 0x8e); - up_idtentry(&idt_entries[36], (uint32_t)vector_irq4, 0x08, 0x8e); - up_idtentry(&idt_entries[37], (uint32_t)vector_irq5, 0x08, 0x8e); - up_idtentry(&idt_entries[38], (uint32_t)vector_irq6, 0x08, 0x8e); - up_idtentry(&idt_entries[39], (uint32_t)vector_irq7, 0x08, 0x8e); - up_idtentry(&idt_entries[40], (uint32_t)vector_irq8, 0x08, 0x8e); - up_idtentry(&idt_entries[41], (uint32_t)vector_irq9, 0x08, 0x8e); - up_idtentry(&idt_entries[42], (uint32_t)vector_irq10, 0x08, 0x8e); - up_idtentry(&idt_entries[43], (uint32_t)vector_irq11, 0x08, 0x8e); - up_idtentry(&idt_entries[44], (uint32_t)vector_irq12, 0x08, 0x8e); - up_idtentry(&idt_entries[45], (uint32_t)vector_irq13, 0x08, 0x8e); - up_idtentry(&idt_entries[46], (uint32_t)vector_irq14, 0x08, 0x8e); - up_idtentry(&idt_entries[47], (uint32_t)vector_irq15, 0x08, 0x8e); - - idt_flush((uint32_t)&idt_ptr); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: up_irqinitialize - ****************************************************************************/ - -void up_irqinitialize(void) -{ - /* currents_regs is non-NULL only while processing an interrupt */ - - current_regs = NULL; - - /* Initialize the IDT */ - - up_idtinit(); - - /* And finally, enable interrupts */ - -#ifndef CONFIG_SUPPRESS_INTERRUPTS - irqrestore(X86_FLAGS_IF); -#endif -} diff --git a/nuttx/arch/x86/src/qemu/qemu_timerisr.c b/nuttx/arch/x86/src/qemu/qemu_timerisr.c index ddc4a5e74..ca51816af 100755 --- a/nuttx/arch/x86/src/qemu/qemu_timerisr.c +++ b/nuttx/arch/x86/src/qemu/qemu_timerisr.c @@ -79,9 +79,6 @@ #define PIT_DIVISOR ((uint32_t)PIT_CLOCK/(uint32_t)CLK_TCK) -#define PIT_MODE 0x43 -#define PIT_CH0 0x40 - /**************************************************************************** * Private Types ****************************************************************************/ @@ -90,26 +87,13 @@ * Private Function Prototypes ****************************************************************************/ -static void pit_outb(uint8_t val, uint16_t addr) __attribute__((noinline)); +static void outb(uint8_t val, uint16_t addr) __attribute__((noinline)); static int up_timerisr(int irq, uint32_t *regs); /**************************************************************************** * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name pit_outb - * - * Description: - * A slightly slower version of outb - * - ****************************************************************************/ - -static void pit_outb(uint8_t val, uint16_t addr) -{ - outb(val, addr); -} - /**************************************************************************** * Function: up_timerisr * @@ -151,12 +135,16 @@ void up_timerinit(void) (void)irq_attach(IRQ0, (xcpt_t)up_timerisr); - /* Send the command byte */ + /* Send the command byte to configure counter 0 */ - pit_outb(0x36, PIT_MODE); + outb(PIT_OCW_MODE_SQUARE|PIT_OCW_RL_DATA|PIT_OCW_COUNTER_0, PIT_REG_COMMAND); /* Set the PIT input frequency divisor */ - pit_outb((uint8_t)(divisor & 0xff), PIT_CH0); - pit_outb((uint8_t)((divisor >> 8) & 0xff), PIT_CH0); + outb((uint8_t)(divisor & 0xff), PIT_REG_COUNTER0); + outb((uint8_t)((divisor >> 8) & 0xff), PIT_REG_COUNTER0); + + /* And enable IRQ0 */ + + up_enable_irq(IRQ0); } diff --git a/nuttx/configs/qemu-i486/nsh/defconfig b/nuttx/configs/qemu-i486/nsh/defconfig index 8244e35bc..3cec37a3b 100644 --- a/nuttx/configs/qemu-i486/nsh/defconfig +++ b/nuttx/configs/qemu-i486/nsh/defconfig @@ -80,7 +80,7 @@ CONFIG_BOARD_LOOPSPERMSEC=999 CONFIG_DRAM_SIZE=0x00100000 CONFIG_DRAM_START=0x00100000 CONFIG_DRAM_END=(CONFIG_DRAM_START+CONFIG_DRAM_SIZE) -CONFIG_ARCH_NOINTC=y +CONFIG_ARCH_NOINTC=n CONFIG_ARCH_STACKDUMP=y CONFIG_ARCH_LEDS=n CONFIG_ARCH_BUTTONS=n diff --git a/nuttx/configs/qemu-i486/ostest/defconfig b/nuttx/configs/qemu-i486/ostest/defconfig index 8b17c30b8..c84f50822 100644 --- a/nuttx/configs/qemu-i486/ostest/defconfig +++ b/nuttx/configs/qemu-i486/ostest/defconfig @@ -80,7 +80,7 @@ CONFIG_BOARD_LOOPSPERMSEC=999 CONFIG_DRAM_SIZE=0x00100000 CONFIG_DRAM_START=0x00100000 CONFIG_DRAM_END=(CONFIG_DRAM_START+CONFIG_DRAM_SIZE) -CONFIG_ARCH_NOINTC=y +CONFIG_ARCH_NOINTC=n CONFIG_ARCH_STACKDUMP=y CONFIG_ARCH_LEDS=n CONFIG_ARCH_BUTTONS=n -- cgit v1.2.3