diff options
Diffstat (limited to 'nuttx/arch/x86/src/qemu/qemu_vectors.S')
-rwxr-xr-x | nuttx/arch/x86/src/qemu/qemu_vectors.S | 395 |
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 */ |