summaryrefslogtreecommitdiff
path: root/nuttx/arch/x86/src/qemu/qemu_vectors.S
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/arch/x86/src/qemu/qemu_vectors.S')
-rwxr-xr-xnuttx/arch/x86/src/qemu/qemu_vectors.S395
1 files changed, 395 insertions, 0 deletions
diff --git a/nuttx/arch/x86/src/qemu/qemu_vectors.S b/nuttx/arch/x86/src/qemu/qemu_vectors.S
new file mode 100755
index 000000000..93cac4b3d
--- /dev/null
+++ b/nuttx/arch/x86/src/qemu/qemu_vectors.S
@@ -0,0 +1,395 @@
+/****************************************************************************
+ * arch/x86/src/qemu/qemu_head.S
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Based on Bran's kernel development tutorials. Rewritten for JamesM's
+ * kernel development tutorials.
+ *
+ * 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 <nuttx/config.h>
+#include <arch/irq.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define KSEG 0x10
+
+/****************************************************************************
+ * Nasm .text
+ ****************************************************************************/
+
+#ifdef CONFIG_X86_NASM
+extern _irq_handler
+extern _isr_handler
+
+/* Trace macros, use like trace 'i' to print char to serial port. */
+
+%macro io_outb 2
+ mov dx, %1 /* param1 = address, param2 = data. */
+ mov al, %2
+ out dx, al
+%endmacro
+
+%macro trace 1
+ io_outb 0x3f8, %1 /* diagnostic character */
+%endmacro
+
+/* This macro creates a stub for an ISR which does NOT pass it's own
+ * error code (adds a dummy errcode byte).
+ */
+
+%macro ISR_NOERRCODE 1
+ global vector_isr%1
+ vector_isr%1:
+ cli /* Disable interrupts firstly. */
+ push byte 0 /* Push a dummy error code. */
+ push byte %1 /* Push the interrupt number. */
+ jmp isr_common /* Go to our common handler code. */
+%endmacro
+
+/* This macro creates a stub for an ISR which passes it's own
+ * error code.
+ */
+
+%macro ISR_ERRCODE 1
+ global vector_isr%1
+ vector_isr%1:
+ cli /* Disable interrupts. */
+ push byte %1 /* Push the interrupt number */
+ jmp isr_common
+%endmacro
+
+/* This macro creates a stub for an IRQ - the first parameter is
+ * the IRQ number, the second is the ISR number it is remapped to.
+ */
+
+%macro IRQ 2
+ global vector_irq%1
+ vector_irq%1:
+ cli
+ push byte 0
+ push byte %2
+ jmp irq_common
+%endmacro
+
+/* The following will be the vector address programmed into the IDT */
+
+ISR_NOERRCODE ISR0
+ISR_NOERRCODE ISR1
+ISR_NOERRCODE ISR2
+ISR_NOERRCODE ISR3
+ISR_NOERRCODE ISR4
+ISR_NOERRCODE ISR5
+ISR_NOERRCODE ISR6
+ISR_NOERRCODE ISR7
+ISR_ERRCODE ISR8
+ISR_NOERRCODE ISR9
+ISR_ERRCODE ISR10
+ISR_ERRCODE ISR11
+ISR_ERRCODE ISR12
+ISR_ERRCODE ISR13
+ISR_ERRCODE ISR14
+ISR_NOERRCODE ISR15
+ISR_NOERRCODE ISR16
+ISR_NOERRCODE ISR17
+ISR_NOERRCODE ISR18
+ISR_NOERRCODE ISR19
+ISR_NOERRCODE ISR20
+ISR_NOERRCODE ISR21
+ISR_NOERRCODE ISR22
+ISR_NOERRCODE ISR23
+ISR_NOERRCODE ISR24
+ISR_NOERRCODE ISR25
+ISR_NOERRCODE ISR26
+ISR_NOERRCODE ISR27
+ISR_NOERRCODE ISR28
+ISR_NOERRCODE ISR29
+ISR_NOERRCODE ISR30
+ISR_NOERRCODE ISR31
+IRQ 0, IRQ0
+IRQ 1, IRQ1
+IRQ 2, IRQ2
+IRQ 3, IRQ3
+IRQ 4, IRQ4
+IRQ 5, IRQ5
+IRQ 6, IRQ6
+IRQ 7, IRQ7
+IRQ 8, IRQ8
+IRQ 9, IRQ9
+IRQ 10, IRQ10
+IRQ 11, IRQ11
+IRQ 12, IRQ12
+IRQ 13, IRQ13
+IRQ 14, IRQ14
+IRQ 15, IRQ15
+
+/* This is our common ISR stub. It saves the processor state, sets up for
+ * kernel mode segments, calls the C-level fault handler, and finally restores
+ * the stack frame.
+ */
+
+isr_common:
+/* trace 'S' */
+ pusha /* Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax */
+
+ mov ax, ds /* Lower 16-bits of eax = ds. */
+ push eax /* Save the data segment descriptor */
+
+ mov ax, KSEG /* Load the kernel data segment descriptor */
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+
+ call _isr_handler
+
+ pop ebx /* Reload the original data segment descriptor */
+ mov ds, bx
+ mov es, bx
+ mov fs, bx
+ mov gs, bx
+
+ popa /* Pops edi,esi,ebp... */
+ add esp, 8 /* Cleans up the pushed error code and pushed ISR number */
+ sti
+ iret /* Pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP */
+
+/* This is our common IRQ stub. It saves the processor state, sets up for
+ * kernel mode segments, calls the C-level fault handler, and finally restores
+ * the stack frame.
+ */
+
+irq_common:
+/* trace 'R' */
+ pusha /* Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax */
+
+ mov ax, ds /* Lower 16-bits of eax = ds. */
+ push eax /* Save the data segment descriptor */
+
+ mov ax, KSEG /* Load the kernel data segment descriptor */
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+
+ call _irq_handler
+
+ pop ebx /* Reload the original data segment descriptor */
+ mov ds, bx
+ mov es, bx
+ mov fs, bx
+ mov gs, bx
+
+ popa /* Pops edi,esi,ebp... */
+ add esp, 8 /* Cleans up the pushed error code and pushed ISR number */
+ sti
+ iret /* Pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP */
+
+#else /* !CONFIG_X86_NASM (GAS) */
+
+/****************************************************************************
+ * GAS .text
+ ****************************************************************************/
+
+ .globl _irq_handler
+ .globl _isr_handler
+
+/* Trace macros, use like trace 'i' to print char to serial port. */
+
+ .macro io_outb, addr, data
+ mov dx, $\addr
+ mov al, $\data
+ out dx, al
+ .endm
+
+ .macro trace, ch
+ io_outb 0x3f8, \ch
+ .endm
+
+/* This macro creates a stub for an ISR which does NOT pass it's own
+ * error code (adds a dummy errcode byte).
+ */
+
+ .macro ISR_NOERRCODE, intno
+ .globl vector_isr\intno
+vector_isr\intno:
+ cli /* Disable interrupts firstly. */
+ push $0 /* Push a dummy error code. */
+ push $\intno /* Push the interrupt number. */
+ jmp isr_common /* Go to the common handler code. */
+ .endm
+
+/* This macro creates a stub for an ISR which passes it's own
+ * error code.
+ */
+
+ .macro ISR_ERRCODE, intno
+ .globl vector_isr\intno
+vector_isr\intno:
+ cli /* Disable interrupts firstly. */
+ push $\intno /* Push the interrupt number. */
+ jmp isr_common /* Go to the common handler code. */
+ .endm
+
+/* This macro creates a stub for an IRQ - the first parameter is
+ * the IRQ number, the second is the ISR number it is remapped to.
+ */
+
+ .macro IRQ, irqno, intno
+ .globl vector_irq\irqno
+vector_irq\irqno:
+ cli /* Disable interrupts firstly. */
+ push $0 /* Push a dummy error code. */
+ push $\intno /* Push the interrupt number. */
+ jmp isr_common /* Go to the common handler code. */
+ .endm
+
+ /* The following will be the vector address programmed into the IDT */
+
+ ISR_NOERRCODE ISR0
+ ISR_NOERRCODE ISR1
+ ISR_NOERRCODE ISR2
+ ISR_NOERRCODE ISR3
+ ISR_NOERRCODE ISR4
+ ISR_NOERRCODE ISR5
+ ISR_NOERRCODE ISR6
+ ISR_NOERRCODE ISR7
+ ISR_ERRCODE ISR8
+ ISR_NOERRCODE ISR9
+ ISR_ERRCODE ISR10
+ ISR_ERRCODE ISR11
+ ISR_ERRCODE ISR12
+ ISR_ERRCODE ISR13
+ ISR_ERRCODE ISR14
+ ISR_NOERRCODE ISR15
+ ISR_NOERRCODE ISR16
+ ISR_NOERRCODE ISR17
+ ISR_NOERRCODE ISR18
+ ISR_NOERRCODE ISR19
+ ISR_NOERRCODE ISR20
+ ISR_NOERRCODE ISR21
+ ISR_NOERRCODE ISR22
+ ISR_NOERRCODE ISR23
+ ISR_NOERRCODE ISR24
+ ISR_NOERRCODE ISR25
+ ISR_NOERRCODE ISR26
+ ISR_NOERRCODE ISR27
+ ISR_NOERRCODE ISR28
+ ISR_NOERRCODE ISR29
+ ISR_NOERRCODE ISR30
+ ISR_NOERRCODE ISR31
+ IRQ 0, IRQ0
+ IRQ 1, IRQ1
+ IRQ 2, IRQ2
+ IRQ 3, IRQ3
+ IRQ 4, IRQ4
+ IRQ 5, IRQ5
+ IRQ 6, IRQ6
+ IRQ 7, IRQ7
+ IRQ 8, IRQ8
+ IRQ 9, IRQ9
+ IRQ 10, IRQ10
+ IRQ 11, IRQ11
+ IRQ 12, IRQ12
+ IRQ 13, IRQ13
+ IRQ 14, IRQ14
+ IRQ 15, IRQ15
+
+/* This is our common ISR stub. It saves the processor state, sets up for
+ * kernel mode segments, calls the C-level fault handler, and finally restores
+ * the stack frame.
+ */
+
+isr_common:
+/* trace 'S' */
+ pusha /* Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax */
+
+ mov %ax, ds /* Lower 16-bits of eax = ds. */
+ pushl %eax /* Save the data segment descriptor */
+
+ mov %ax, KSEG /* Load the kernel data segment descriptor */
+ mov ds, %ax
+ mov es, %ax
+ mov fs, %ax
+ mov gs, %ax
+
+ call _isr_handler
+
+ pop ebx /* Reload the original data segment descriptor */
+ mov ds, %bx
+ mov es, %bx
+ mov fs, %bx
+ mov gs, %bx
+
+ popa /* Pops edi,esi,ebp... */
+ add %esp, 8 /* Cleans up the pushed error code and pushed ISR number */
+ sti
+ iret /* Pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP */
+
+/* This is our common IRQ stub. It saves the processor state, sets up for
+ * kernel mode segments, calls the C-level fault handler, and finally restores
+ * the stack frame.
+ */
+
+irq_common:
+/* trace 'R' */
+ pusha /* Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax */
+
+ mov %ax, ds /* Lower 16-bits of eax = ds. */
+ push %eax /* Save the data segment descriptor */
+
+ mov %ax, KSEG /* Load the kernel data segment descriptor */
+ mov ds, %ax
+ mov es, %ax
+ mov fs, %ax
+ mov gs, %ax
+
+ call _irq_handler
+
+ pop %ebx /* Reload the original data segment descriptor */
+ mov ds, %bx
+ mov es, %bx
+ mov fs, %bx
+ mov gs, %bx
+
+ popa /* Pops edi,esi,ebp... */
+ add %esp, 8 /* Cleans up the pushed error code and pushed ISR number */
+ sti
+ iret /* Pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP */
+ .end
+#endif /* CONFIG_X86_NASM */