Fix basic QEMU port
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3357 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
916b9b3435
commit
177d69d212
@ -74,7 +74,7 @@
|
||||
|
||||
#if defined(CONFIG_USE_SERIALDRIVER) && defined(HAVE_UART)
|
||||
|
||||
/* Configuration *********************************************************************/
|
||||
/* Configuration ************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
@ -281,7 +281,7 @@ static uart_dev_t g_uart3port =
|
||||
# ifdef CONFIG_LPC17_UART3
|
||||
# define TTYS3_DEV g_uart3port /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS2;UART3=ttyS3 */
|
||||
# else
|
||||
undef TTYS3_DEV /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS;No ttyS3 */
|
||||
# undef TTYS3_DEV /* UART0=ttyS0;UART1=ttyS1;UART2=ttyS;No ttyS3 */
|
||||
# endif
|
||||
# else
|
||||
# ifdef CONFIG_LPC17_UART3
|
||||
@ -780,9 +780,8 @@ static inline uint32_t lpc17_uartdl(uint32_t baud, uint8_t divcode)
|
||||
* Name: up_setup
|
||||
*
|
||||
* Description:
|
||||
* Configure the UART baud, bits, parity, fifos, etc. This
|
||||
* method is called the first time that the serial port is
|
||||
* opened.
|
||||
* Configure the UART baud, bits, parity, fifos, etc. This method is
|
||||
* called the first time that the serial port is opened.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
@ -858,8 +857,7 @@ static int up_setup(struct uart_dev_s *dev)
|
||||
* Name: up_shutdown
|
||||
*
|
||||
* Description:
|
||||
* Disable the UART. This method is called when the serial
|
||||
* port is closed
|
||||
* Disable the UART. This method is called when the serial port is closed
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
@ -924,12 +922,11 @@ static void up_detach(struct uart_dev_s *dev)
|
||||
* Name: up_interrupt
|
||||
*
|
||||
* Description:
|
||||
* This is the UART interrupt handler. It will be invoked
|
||||
* when an interrupt received on the 'irq' It should call
|
||||
* uart_transmitchars or uart_receivechar to perform the
|
||||
* appropriate data transfers. The interrupt handling logic\
|
||||
* must be able to map the 'irq' number into the approprite
|
||||
* uart_dev_s structure in order to call these functions.
|
||||
* This is the UART interrupt handler. It will be invoked when an
|
||||
* interrupt received on the 'irq' It should call uart_transmitchars or
|
||||
* uart_receivechar to perform the appropriate data transfers. The
|
||||
* interrupt handling logic must be able to map the 'irq' number into the
|
||||
* appropriate uart_dev_s structure in order to call these functions.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
|
@ -184,7 +184,7 @@
|
||||
#define UART_IIR_INTID_MASK (7 << UART_IIR_INTID_SHIFT)
|
||||
# define UART_IIR_INTID_MSI (0 << UART_IIR_INTID_SHIFT) /* Modem Status (UART1 only) */
|
||||
# define UART_IIR_INTID_THRE (1 << UART_IIR_INTID_SHIFT) /* THRE Interrupt */
|
||||
# define UART_IIR_INTID_RDA (2 << UART_IIR_INTID_SHIFT) /* 2a - Receive Data Available (RDA */
|
||||
# define UART_IIR_INTID_RDA (2 << UART_IIR_INTID_SHIFT) /* 2a - Receive Data Available (RDA) */
|
||||
# define UART_IIR_INTID_RLS (3 << UART_IIR_INTID_SHIFT) /* 1 - Receive Line Status (RLS) */
|
||||
# define UART_IIR_INTID_CTI (6 << UART_IIR_INTID_SHIFT) /* 2b - Character Time-out Indicator (CTI) */
|
||||
/* Bits 4-5: Reserved */
|
||||
|
@ -42,6 +42,8 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
.file "i486_utils.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
@ -49,73 +51,14 @@
|
||||
#define KSEG 0x10
|
||||
|
||||
/****************************************************************************
|
||||
* Nasm
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_X86_NASM
|
||||
|
||||
/****************************************************************************
|
||||
* Nasm externals
|
||||
****************************************************************************/
|
||||
|
||||
global gdt_flush
|
||||
global idt_flush
|
||||
|
||||
/****************************************************************************
|
||||
* Nasm macros
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Nasm .text
|
||||
****************************************************************************/
|
||||
|
||||
SECTION .text
|
||||
BITS 32
|
||||
|
||||
/****************************************************************************
|
||||
* Name: gdt_flush
|
||||
****************************************************************************/
|
||||
|
||||
gdt_flush:
|
||||
mov eax, [esp+4] /* Get the pointer to the GDT, passed as a parameter */
|
||||
lgdt [eax] /* Load the new GDT pointer */
|
||||
|
||||
mov $KSEG, ax /* KSEG is the offset in the GDT to our data segment */
|
||||
mov ax, ds /* Load all data segment selectors */
|
||||
mov ax, es
|
||||
mov ax, fs
|
||||
mov ax, gs
|
||||
mov ax, ss
|
||||
jmp 0x08:.gflush /* 0x08 is the offset to our code segment: Far jump! */
|
||||
.gflush:
|
||||
ret
|
||||
|
||||
/****************************************************************************
|
||||
* Name: idt_flush
|
||||
****************************************************************************/
|
||||
|
||||
idt_flush:
|
||||
mov eax, [esp+4] /* Get the pointer to the IDT, passed as a parameter */
|
||||
lidt [eax] /* Load the IDT pointer */
|
||||
ret
|
||||
|
||||
#else /* !CONFIG_X86_NASM (GAS) */
|
||||
|
||||
/****************************************************************************
|
||||
* GAS
|
||||
****************************************************************************/
|
||||
|
||||
.file "i486_utils.S"
|
||||
|
||||
/****************************************************************************
|
||||
* GAS Globals
|
||||
* Globals
|
||||
****************************************************************************/
|
||||
|
||||
.globl gdt_flush
|
||||
.globl idt_flush
|
||||
|
||||
/****************************************************************************
|
||||
* GAS .text
|
||||
* .text
|
||||
****************************************************************************/
|
||||
|
||||
.text
|
||||
@ -151,4 +94,3 @@ idt_flush:
|
||||
ret
|
||||
.size idt_flush, . - idt_flush
|
||||
.end
|
||||
#endif /* CONFIG_X86_NASM */
|
||||
|
@ -45,34 +45,36 @@
|
||||
#include <arch/irq.h>
|
||||
#include "up_internal.h"
|
||||
|
||||
.file "qemu_fullcontextrestore.S"
|
||||
|
||||
/**************************************************************************
|
||||
* Pre-processor Definitions
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Private Types
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Private Function Prototypes
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Global Variables
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Private Variables
|
||||
**************************************************************************/
|
||||
/****************************************************************************
|
||||
* Macros
|
||||
****************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Private Functions
|
||||
**************************************************************************/
|
||||
/* Trace macros, use like trace 'i' to print char to serial port. */
|
||||
|
||||
.macro trace, ch
|
||||
#ifdef CONFIG_DEBUG
|
||||
mov $0x3f8, %dx
|
||||
mov $\ch, %al
|
||||
out %al, %dx
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/**************************************************************************
|
||||
* Public Functions
|
||||
**************************************************************************/
|
||||
|
||||
.text
|
||||
|
||||
/**************************************************************************
|
||||
* Name: up_fullcontextrestore
|
||||
*
|
||||
@ -81,11 +83,6 @@
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifdef CONFIG_X86_NASM
|
||||
# warning "No Nasm support"
|
||||
#else
|
||||
.file "qemu_fullcontextrestore.S"
|
||||
.text
|
||||
.globl up_fullcontextrestore
|
||||
.type up_fullcontextrestore, @function
|
||||
up_fullcontextrestore:
|
||||
@ -105,38 +102,54 @@ up_fullcontextrestore:
|
||||
|
||||
movl (4*REG_SP)(%eax), %esp
|
||||
|
||||
/* Save the return address, EFLAGS, and the values as well the
|
||||
* values of EBX and EAC on the new stack.
|
||||
/* Create an interrupt stack frame for the final iret.
|
||||
*
|
||||
* SP Before ->
|
||||
* SS
|
||||
* ESP
|
||||
* EFLAGS
|
||||
* CS
|
||||
* SP After -> EIP
|
||||
*/
|
||||
|
||||
movl (4*REG_EIP)(%eax), %ebx
|
||||
mov (4*REG_SS)(%eax), %ebx
|
||||
push %ebx
|
||||
movl (4*REG_SP)(%eax), %ebx
|
||||
push %ebx
|
||||
movl (4*REG_EFLAGS)(%eax), %ebx
|
||||
push %ebx
|
||||
mov (4*REG_CS)(%eax), %ebx
|
||||
push %ebx
|
||||
movl (4*REG_EIP)(%eax), %ebx
|
||||
push %ebx
|
||||
|
||||
/* Save the value of EAX on the stack too */
|
||||
|
||||
movl (4*REG_EAX)(%eax), %ebx
|
||||
push %ebx
|
||||
|
||||
/* Now restore the remaining registers */
|
||||
|
||||
movl (4*REG_EDI)(%eax), %edi
|
||||
movl (4*REG_ESI)(%eax), %esi
|
||||
movl (4*REG_EDI)(%eax), %edi
|
||||
movl (4*REG_EBP)(%eax), %ebp
|
||||
movl (4*REG_EBX)(%eax), %ebx
|
||||
movl (4*REG_EDX)(%eax), %edx
|
||||
movl (4*REG_ECX)(%eax), %ecx
|
||||
movl (4*REG_EBX)(%eax), %ebx
|
||||
|
||||
/* Restore the segment registers */
|
||||
/* Restore the data segment register. I think there is an issue that will
|
||||
* need to be address here at some time: If the register save area is in
|
||||
* one data segment and the stack is in another, then the above would not
|
||||
* work (and, conversely, if they are in the same data segment, the
|
||||
* following is unnecessary and redundant).
|
||||
*/
|
||||
|
||||
mov (4*REG_DS)(%eax), %ds
|
||||
mov (4*REG_CS)(%eax), %cs
|
||||
mov (4*REG_SS)(%eax), %ss
|
||||
|
||||
/* Restore the correct value of EAX, EBX, and the EFLAGS then return */
|
||||
/* Restore the correct value of EAX and then return */
|
||||
|
||||
popl %eax
|
||||
popf
|
||||
ret
|
||||
iret
|
||||
.size up_fullcontextrestore, . - up_fullcontextrestore
|
||||
.end
|
||||
#endif /* CONFIG_X86_NASM */
|
||||
|
||||
|
@ -39,6 +39,8 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
.file "qemu_head.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor definitions
|
||||
****************************************************************************/
|
||||
@ -56,94 +58,35 @@
|
||||
#define HEAP_BASE (STACKBASE+CONFIG_IDLETHREAD_STACKSIZE)
|
||||
|
||||
/****************************************************************************
|
||||
* Nasm .text
|
||||
* Macros
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_X86_NASM
|
||||
global __start /* Making entry point visible to linker */
|
||||
global g_heapbase /* The start of the heap */
|
||||
extern os_start /* os_start is defined elsewhere */
|
||||
extern up_lowsetup /* up_lowsetup is defined elsewhere */
|
||||
|
||||
/* Setting up the Multiboot header - see GRUB docs for details */
|
||||
/* Trace macros, use like trace 'i' to print char to serial port. */
|
||||
|
||||
MODULEALIGN equ 1<<0 /* Align loaded modules on page boundaries */
|
||||
MEMINFO equ 1<<1 /* Provide memory map */
|
||||
FLAGS equ MODULEALIGN | MEMINFO /* This is the Multiboot 'flag' field */
|
||||
MAGIC equ 0x1badb002 /* 'magic number' lets bootloader find the header */
|
||||
CHECKSUM equ -(MAGIC + FLAGS) /* Checksum required */
|
||||
|
||||
section .text
|
||||
align 4
|
||||
MultiBootHeader:
|
||||
dd MAGIC
|
||||
dd FLAGS
|
||||
dd CHECKSUM
|
||||
|
||||
__start:
|
||||
/* Set up the stack */
|
||||
|
||||
mov esp, idle_stack + CONFIG_IDLETHREAD_STACKSIZE
|
||||
|
||||
/* Multiboot setup */
|
||||
|
||||
push eax /* Pass Multiboot magic number */
|
||||
push ebx /* Pass Multiboot info structure */
|
||||
|
||||
/* Initialize and start NuttX */
|
||||
|
||||
call up_lowsetup /* Low-level, pre-OS initialization */
|
||||
call os_start /* Start NuttX */
|
||||
|
||||
/* NuttX will not return */
|
||||
|
||||
cli
|
||||
hang:
|
||||
hlt /* Halt machine should NuttX return */
|
||||
jmp hang
|
||||
|
||||
/****************************************************************************
|
||||
* .bss
|
||||
****************************************************************************/
|
||||
|
||||
/* The stack for the IDLE task thread is declared in .bss. NuttX boots and
|
||||
* initializes on the IDLE thread, then at the completion of OS startup, this
|
||||
* thread becomes the thread that executes when there is nothing else to
|
||||
* do in the system (see up_idle()).
|
||||
*/
|
||||
|
||||
section .bss
|
||||
align 4
|
||||
idle_stack:
|
||||
resb CONFIG_IDLETHREAD_STACKSIZE
|
||||
.macro trace, ch
|
||||
#ifdef CONFIG_DEBUG
|
||||
mov $0x3f8, %dx
|
||||
mov $\ch, %al
|
||||
out %al, %dx
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/****************************************************************************
|
||||
* .rodata
|
||||
* Global Symbols
|
||||
****************************************************************************/
|
||||
|
||||
section .rodata
|
||||
|
||||
/* HEAP BASE: _sbss is the start of the BSS region (see ld.script) _ebss is
|
||||
* the end of the BSS region (see ld.script). The heap continues from there
|
||||
* until the end of memory.
|
||||
*/
|
||||
|
||||
align 4
|
||||
g_heapbase:
|
||||
dd _ebss
|
||||
|
||||
#else /* !CONFIG_X86_NASM (GAS) */
|
||||
|
||||
/****************************************************************************
|
||||
* GAS .text
|
||||
****************************************************************************/
|
||||
|
||||
.file "qemu_head.S"
|
||||
.global __start /* Making entry point visible to linker */
|
||||
.global os_start /* os_start is defined elsewhere */
|
||||
.global up_lowsetup /* up_lowsetup is defined elsewhere */
|
||||
.global g_heapbase /* The start of the heap */
|
||||
|
||||
/****************************************************************************
|
||||
* .text
|
||||
****************************************************************************/
|
||||
/****************************************************************************
|
||||
* Multiboot Header
|
||||
****************************************************************************/
|
||||
|
||||
/* Setting up the Multiboot header - see GRUB docs for details */
|
||||
|
||||
.set ALIGN, 1<<0 /* Align loaded modules on page boundaries */
|
||||
@ -158,28 +101,24 @@ g_heapbase:
|
||||
.long FLAGS
|
||||
.long CHECKSUM
|
||||
|
||||
/****************************************************************************
|
||||
* Name: Start
|
||||
****************************************************************************/
|
||||
|
||||
.type __start, @function
|
||||
__start:
|
||||
/* Set up the stack */
|
||||
mov $'a', %ax
|
||||
mov $0x3f8, %dx
|
||||
outb %al, %dx
|
||||
|
||||
mov $(idle_stack + CONFIG_IDLETHREAD_STACKSIZE), %esp
|
||||
|
||||
/* Multiboot setup */
|
||||
|
||||
push %eax /* Multiboot magic number */
|
||||
push %ebx /* Multiboot data structure */
|
||||
mov $'b', %ax
|
||||
mov $0x3f8, %dx
|
||||
outb %al, %dx
|
||||
|
||||
/* Initialize and start NuttX */
|
||||
|
||||
call up_lowsetup /* Low-level, pre-OS initialization */
|
||||
mov $'c', %ax
|
||||
mov $0x3f8, %dx
|
||||
outb %al, %dx
|
||||
call os_start /* Start NuttX */
|
||||
|
||||
/* NuttX will not return */
|
||||
@ -220,4 +159,3 @@ g_heapbase:
|
||||
.long _ebss
|
||||
.size g_heapbase, . - g_heapbase
|
||||
.end
|
||||
#endif /* CONFIG_X86_NASM */
|
||||
|
@ -78,6 +78,8 @@ uint32_t *current_regs;
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct idt_entry_s idt_entries[256];
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
@ -171,10 +173,7 @@ static void up_idtentry(struct idt_entry_s *entry, uint32_t base,
|
||||
|
||||
static inline void up_idtinit(void)
|
||||
{
|
||||
/* This uses a ton of stack! */
|
||||
|
||||
struct idt_entry_s idt_entries[256];
|
||||
struct idt_ptr_s idt_ptr;
|
||||
struct idt_ptr_s idt_ptr;
|
||||
|
||||
idt_ptr.limit = sizeof(struct idt_entry_s) * 256 - 1;
|
||||
idt_ptr.base = (uint32_t)&idt_entries;
|
||||
|
@ -52,6 +52,8 @@
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static struct gdt_entry_s gdt_entries[5];
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
@ -93,8 +95,7 @@ static void up_gdtentry(struct gdt_entry_s *entry, uint32_t base,
|
||||
|
||||
static void up_gdtinit(void)
|
||||
{
|
||||
struct gdt_entry_s gdt_entries[5];
|
||||
struct gdt_ptr_s gdt_ptr;
|
||||
struct gdt_ptr_s gdt_ptr;
|
||||
|
||||
up_gdtentry(&gdt_entries[0], 0, 0, 0, 0); /* Null segment */
|
||||
up_gdtentry(&gdt_entries[1], 0, 0xffffffff, 0x9a, 0xcf); /* Code segment */
|
||||
|
@ -45,33 +45,31 @@
|
||||
#include <arch/irq.h>
|
||||
#include "up_internal.h"
|
||||
|
||||
/**************************************************************************
|
||||
* Private Definitions
|
||||
**************************************************************************/
|
||||
.file "qemu_saveusercontext.S"
|
||||
|
||||
/**************************************************************************
|
||||
* Private Types
|
||||
* Pre-processor Definitions
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Private Function Prototypes
|
||||
**************************************************************************/
|
||||
/****************************************************************************
|
||||
* Macros
|
||||
****************************************************************************/
|
||||
|
||||
/* Trace macros, use like trace 'i' to print char to serial port. */
|
||||
|
||||
.macro trace, ch
|
||||
#ifdef CONFIG_DEBUG
|
||||
mov $0x3f8, %dx
|
||||
mov $\ch, %al
|
||||
out %al, %dx
|
||||
#endif
|
||||
.endm
|
||||
|
||||
/**************************************************************************
|
||||
* Global Variables
|
||||
* .text
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Private Variables
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Private Functions
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* Public Functions
|
||||
**************************************************************************/
|
||||
.text
|
||||
|
||||
/**************************************************************************
|
||||
* Name: up_saveusercontext
|
||||
@ -95,11 +93,6 @@
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
#ifdef CONFIG_X86_NASM
|
||||
# warning "No Nasm support"
|
||||
#else
|
||||
.file "qemu_saveusercontext.S"
|
||||
.text
|
||||
.globl up_saveusercontext
|
||||
.type up_saveusercontext, @function
|
||||
up_saveusercontext:
|
||||
@ -151,4 +144,3 @@ up_saveusercontext:
|
||||
ret
|
||||
.size up_saveusercontext, . - up_saveusercontext
|
||||
.end
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/****************************************************************************
|
||||
* arch/x86/src/qemu/qemu_head.S
|
||||
* arch/x86/src/qemu/qemu_head.S
|
||||
*
|
||||
* Copyright (C) 2011 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
@ -43,6 +43,8 @@
|
||||
#include <nuttx/config.h>
|
||||
#include <arch/irq.h>
|
||||
|
||||
.file "qemu_vectors.S"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
@ -50,242 +52,20 @@
|
||||
#define KSEG 0x10
|
||||
|
||||
/****************************************************************************
|
||||
* Nasm .text
|
||||
* .text
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_X86_NASM
|
||||
.text
|
||||
|
||||
/****************************************************************************
|
||||
* Nasm externals
|
||||
****************************************************************************/
|
||||
|
||||
extern irq_handler
|
||||
extern isr_handler
|
||||
|
||||
/****************************************************************************
|
||||
* Nasm macros
|
||||
****************************************************************************/
|
||||
|
||||
/* 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
|
||||
|
||||
/****************************************************************************
|
||||
* Nasm vectors
|
||||
****************************************************************************/
|
||||
|
||||
/* 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
|
||||
|
||||
/****************************************************************************
|
||||
* Name: isr_common
|
||||
*
|
||||
* Description:
|
||||
* This is the common ISR logic. 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
|
||||
|
||||
/* The current value of the SP points to the beginning of the state save
|
||||
* structure. Save that on the stack as the input parameter to isr_handler.
|
||||
*/
|
||||
|
||||
mov esp, eax
|
||||
push eax
|
||||
call isr_handler
|
||||
jmp .Lreturn
|
||||
|
||||
/****************************************************************************
|
||||
* Name: irq_common
|
||||
*
|
||||
* Description:
|
||||
* This is the common IRQ logic. 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
|
||||
|
||||
/* The current value of the SP points to the beginning of the state save
|
||||
* structure. Save that on the stack as the input parameter to irq_handler.
|
||||
*/
|
||||
|
||||
mov esp, eax
|
||||
push eax
|
||||
call irq_handler
|
||||
|
||||
/* The common return point for both isr_handler and irq_handler */
|
||||
|
||||
.Lreturn:
|
||||
add 4, esp
|
||||
|
||||
/* EAX may possibly hold a pointer to a different regiser save area on
|
||||
* return. Are we switching to a new context?
|
||||
*/
|
||||
|
||||
cmp eax, esp
|
||||
je .Lnoswitch
|
||||
|
||||
/* A context swith will be performed. EAX holds the address of the new
|
||||
* register save structure.
|
||||
*
|
||||
* 'Jump' to up_fullcontextrestore(). We perform a call here, but that function
|
||||
* never returns. The address of the new register save block is the argument
|
||||
* to the up_fullcontextrestore().
|
||||
*/
|
||||
|
||||
push eax
|
||||
jmp up_fullcontext
|
||||
|
||||
.Lnoswitch:
|
||||
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
|
||||
****************************************************************************/
|
||||
|
||||
.file "qemu_vectors.S"
|
||||
|
||||
/****************************************************************************
|
||||
* GAS globals
|
||||
* Globals
|
||||
****************************************************************************/
|
||||
|
||||
.globl irq_handler
|
||||
.globl isr_handler
|
||||
|
||||
/****************************************************************************
|
||||
* GAS macros
|
||||
* Macros
|
||||
****************************************************************************/
|
||||
|
||||
/* Trace macros, use like trace 'i' to print char to serial port. */
|
||||
@ -334,7 +114,10 @@ vector_irq\irqno:
|
||||
jmp isr_common /* Go to the common handler code. */
|
||||
.endm
|
||||
|
||||
/* The following will be the vector address programmed into the IDT */
|
||||
/****************************************************************************
|
||||
* IDT Vectors
|
||||
****************************************************************************/
|
||||
/* The following will be the vector addresses programmed into the IDT */
|
||||
|
||||
ISR_NOERRCODE ISR0
|
||||
ISR_NOERRCODE ISR1
|
||||
@ -487,4 +270,3 @@ irq_common:
|
||||
iret /* Pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP */
|
||||
.size irq_common, . - irq_common
|
||||
.end
|
||||
#endif /* CONFIG_X86_NASM */
|
||||
|
Loading…
x
Reference in New Issue
Block a user