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:
patacongo 2011-03-10 00:58:10 +00:00
parent 916b9b3435
commit 177d69d212
9 changed files with 117 additions and 453 deletions

View File

@ -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.
*
****************************************************************************/

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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;

View File

@ -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 */

View File

@ -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

View File

@ -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 */