import lm3s, lpc2148/lpc2478, x86/qemu, AT91SAM7S/7X, s3c44b0, STM32F103ZE bsp
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@3 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
parent
bda4730a94
commit
1d74273319
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* File : __udivsi3.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006, RT-Thread Develop Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://openlab.rt-thread.com/license/LICENSE
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2006-10-09 Bernard the first version for i386
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
typedef rt_uint32_t uint32_t;
|
||||
typedef rt_int32 int32_t;
|
||||
|
||||
uint32_t __udivsi3(uint32_t num, uint32_t den)
|
||||
{
|
||||
uint32_t quot = 0, qbit = 1;
|
||||
|
||||
if (den == 0)
|
||||
{
|
||||
asm volatile ("int $0");
|
||||
return 0; /* If trap returns... */
|
||||
}
|
||||
|
||||
/* Left-justify denominator and count shift */
|
||||
while ((int32_t) den >= 0)
|
||||
{
|
||||
den <<= 1;
|
||||
qbit <<= 1;
|
||||
}
|
||||
|
||||
while (qbit)
|
||||
{
|
||||
if (den <= num)
|
||||
{
|
||||
num -= den;
|
||||
quot += qbit;
|
||||
}
|
||||
den >>= 1;
|
||||
qbit >>= 1;
|
||||
}
|
||||
|
||||
return quot;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* File : __umodsi3.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006, RT-Thread Develop Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://openlab.rt-thread.com/license/LICENSE
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2006-10-09 Bernard the first version for i386
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
typedef rt_uint32_t uint32_t;
|
||||
typedef rt_int32 int32_t;
|
||||
|
||||
uint32_t __umodsi3(uint32_t num, uint32_t den)
|
||||
{
|
||||
register uint32_t quot = 0, qbit = 1;
|
||||
|
||||
if (den == 0)
|
||||
{
|
||||
asm volatile ("int $0");
|
||||
return 0; /* if trap returns... */
|
||||
}
|
||||
|
||||
/* left-justify denominator and count shift */
|
||||
while ((int32_t) den >= 0)
|
||||
{
|
||||
den <<= 1;
|
||||
qbit <<= 1;
|
||||
}
|
||||
|
||||
while (qbit)
|
||||
{
|
||||
if (den <= num)
|
||||
{
|
||||
num -= den;
|
||||
quot += qbit;
|
||||
}
|
||||
den >>= 1;
|
||||
qbit >>= 1;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* File : backtrace.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006, 2008 RT-Thread Development Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://openlab.rt-thread.com/license/LICENSE
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2008-07-29 Bernard first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
void rt_hw_backtrace(rt_uint32_t *fp, rt_uint32_t thread_entry)
|
||||
{
|
||||
/* no implementation */
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* File : context.S
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://openlab.rt-thread.com/license/LICENSE
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2006-09-15 QiuYi The first version
|
||||
* 2006-10-09 Bernard add rt_hw_context_switch_to implementation
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup ia32
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
/*
|
||||
* void rt_hw_context_switch(rt_uint32 from, rt_uint32 to);
|
||||
*/
|
||||
.globl rt_hw_context_switch
|
||||
rt_hw_context_switch:
|
||||
pushfl /*pushed eflags*/
|
||||
push %cs /*push cs register*/
|
||||
pushl 0x8(%esp) /*pushed eip register*/
|
||||
pushl $0 /*fill irqno*/
|
||||
push %ds /*push ds register*/
|
||||
push %es /*push es register*/
|
||||
pushal /*push eax,ecx,edx,ebx,esp,ebp,esp,edi registers*/
|
||||
|
||||
movl 0x40(%esp), %eax /*to thread TCB*/
|
||||
movl 0x3c(%esp), %ebx /*from thread TCB*/
|
||||
|
||||
movl %esp, (%ebx) /*store esp in preempted tasks TCB*/
|
||||
movl (%eax), %esp /*get new task stack pointer*/
|
||||
|
||||
popal /*restore new task TCB*/
|
||||
pop %es
|
||||
pop %ds
|
||||
add $4,%esp /*skip irqno*/
|
||||
iret
|
||||
|
||||
/*
|
||||
* void rt_hw_context_switch_to(rt_uint32 to);
|
||||
*/
|
||||
.globl rt_hw_context_switch_to
|
||||
rt_hw_context_switch_to:
|
||||
push %ebp
|
||||
movl %esp, %ebp
|
||||
|
||||
movl 0x8(%ebp), %eax /* to thread TCB */
|
||||
movl (%eax), %esp /* get new task stack pointer */
|
||||
|
||||
popal /* restore new task TCB*/
|
||||
pop %es
|
||||
pop %ds
|
||||
add $4, %esp /* skip irqno */
|
||||
iret
|
||||
|
||||
/*
|
||||
* void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to);
|
||||
*/
|
||||
.globl rt_thread_switch_interrput_flag
|
||||
.globl rt_interrupt_from_thread
|
||||
.globl rt_interrupt_to_thread
|
||||
.globl rt_hw_context_switch_interrupt
|
||||
rt_hw_context_switch_interrupt:
|
||||
pushl %ebp
|
||||
movl %esp, %ebp
|
||||
movl 0xc(%ebp), %eax
|
||||
movl 0x8(%ebp), %ebx
|
||||
|
||||
movl $rt_thread_switch_interrput_flag, %ecx
|
||||
movl (%ecx), %edx
|
||||
cmp $0x1, %edx
|
||||
jz _reswitch
|
||||
|
||||
movl $0x1, %edx /*set rt_thread_switch_interrput_flag to 1*/
|
||||
movl %edx, (%ecx)
|
||||
movl $rt_interrupt_from_thread, %edx /*set rt_interrupt_from_thread*/
|
||||
movl %ebx, (%edx)
|
||||
_reswitch:
|
||||
movl $rt_interrupt_to_thread, %edx /*set rt_interrupt_to_thread*/
|
||||
movl %eax, (%edx)
|
||||
leave
|
||||
ret
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* File : hdisr.S
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://openlab.rt-thread.com/license/LICENSE
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup I386
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
#define ENTRY(proc)\
|
||||
.align 2;\
|
||||
.globl proc;\
|
||||
.type proc,@function;\
|
||||
proc:
|
||||
#define HDINTERRUPTFNC(name,num) \
|
||||
ENTRY(name)\
|
||||
pushl $(num);\
|
||||
jmp _hdinterrupts;\
|
||||
.data;\
|
||||
.long name;\
|
||||
.text
|
||||
|
||||
.globl hdinterrupt_func
|
||||
.data
|
||||
.align 4
|
||||
.type hdinterrupt_func,@object
|
||||
hdinterrupt_func :
|
||||
.text
|
||||
|
||||
/* the external device interrupts */
|
||||
HDINTERRUPTFNC(irq0, 0)
|
||||
HDINTERRUPTFNC(irq1, 1)
|
||||
HDINTERRUPTFNC(irq2, 2)
|
||||
HDINTERRUPTFNC(irq3, 3)
|
||||
HDINTERRUPTFNC(irq4, 4)
|
||||
HDINTERRUPTFNC(irq5, 5)
|
||||
HDINTERRUPTFNC(irq6, 6)
|
||||
HDINTERRUPTFNC(irq7, 7)
|
||||
HDINTERRUPTFNC(irq8, 8)
|
||||
HDINTERRUPTFNC(irq9, 9)
|
||||
HDINTERRUPTFNC(irq10, 10)
|
||||
HDINTERRUPTFNC(irq11, 11)
|
||||
HDINTERRUPTFNC(irq12, 12)
|
||||
HDINTERRUPTFNC(irq13, 13)
|
||||
HDINTERRUPTFNC(irq14, 14)
|
||||
HDINTERRUPTFNC(irq15, 15)
|
||||
|
||||
.p2align 4,0x90
|
||||
.globl _hdinterrupts
|
||||
.type _hdinterrupts,@function
|
||||
.globl rt_interrupt_enter
|
||||
.globl rt_interrupt_leave
|
||||
.globl isr_table
|
||||
.globl rt_thread_switch_interrput_flag
|
||||
.globl rt_interrupt_from_thread
|
||||
.globl rt_interrupt_to_thread
|
||||
|
||||
_hdinterrupts:
|
||||
push %ds
|
||||
push %es
|
||||
pushal
|
||||
movw $0x10, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
pushl %esp
|
||||
call rt_interrupt_enter
|
||||
movl %esp, %eax /* get irqno */
|
||||
addl $0x2c, %eax
|
||||
movl (%eax), %eax /* each item takes up 4bytes in isr_table,equl to isr_table[irqno] */
|
||||
shll $0x2, %eax
|
||||
movl $isr_table, %ebx
|
||||
addl %eax,%ebx
|
||||
call *(%ebx)
|
||||
call rt_interrupt_leave
|
||||
|
||||
/* if rt_thread_switch_interrput_flag set, jump to _interrupt_thread_switch and don't return */
|
||||
movl $rt_thread_switch_interrput_flag, %eax
|
||||
movl (%eax), %ebx
|
||||
cmp $0x1, %ebx
|
||||
jz _interrupt_thread_switch
|
||||
|
||||
popl %esp
|
||||
popal
|
||||
pop %es
|
||||
pop %ds
|
||||
add $4,%esp
|
||||
iret
|
||||
|
||||
_interrupt_thread_switch:
|
||||
popl %esp
|
||||
|
||||
movl $0x0, %ebx
|
||||
movl %ebx, (%eax)
|
||||
|
||||
movl $rt_interrupt_from_thread, %eax
|
||||
movl (%eax), %ebx
|
||||
movl %esp, (%ebx)
|
||||
|
||||
movl $rt_interrupt_to_thread, %ecx
|
||||
movl (%ecx), %edx
|
||||
movl (%edx), %esp
|
||||
|
||||
popal
|
||||
pop %es
|
||||
pop %ds
|
||||
add $4,%esp
|
||||
iret
|
||||
|
||||
/*@}*/
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* File : bsp.h
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006, RT-Thread Develop Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://openlab.rt-thread.com/license/LICENSE
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2006-09-15 QiuYi the first version */
|
||||
|
||||
#ifndef __BSP_H_
|
||||
#define __BSP_H_
|
||||
|
||||
#include <i386.h>
|
||||
|
||||
/*******************************************************************/
|
||||
/* Timer Register */
|
||||
/*******************************************************************/
|
||||
#define TIMER_CNTR0 (IO_TIMER1 + 0) /* timer 0 counter port */
|
||||
#define TIMER_CNTR1 (IO_TIMER1 + 1) /* timer 1 counter port */
|
||||
#define TIMER_CNTR2 (IO_TIMER1 + 2) /* timer 2 counter port */
|
||||
#define TIMER_MODE (IO_TIMER1 + 3) /* timer mode port */
|
||||
#define TIMER_SEL0 0x00 /* select counter 0 */
|
||||
#define TIMER_SEL1 0x40 /* select counter 1 */
|
||||
#define TIMER_INTTC 0x00 /* mode 0, intr on terminal cnt */
|
||||
#define TIMER_ONESHOT 0x02 /* mode 1, one shot */
|
||||
#define TIMER_RATEGEN 0x04 /* mode 2, rate generator */
|
||||
#define TIMER_SQWAVE 0x06 /* mode 3, square wave */
|
||||
#define TIMER_SWSTROBE 0x08 /* mode 4, s/w triggered strobe */
|
||||
#define TIMER_HWSTROBE 0x0a /* mode 5, h/w triggered strobe */
|
||||
#define TIMER_LATCH 0x00 /* latch counter for reading */
|
||||
#define TIMER_LSB 0x10 /* r/w counter LSB */
|
||||
#define TIMER_MSB 0x20 /* r/w counter MSB */
|
||||
#define TIMER_16BIT 0x30 /* r/w counter 16 bits, LSB first */
|
||||
#define TIMER_BCD 0x01 /* count in BCD */
|
||||
|
||||
#define TIMER_FREQ 1193182
|
||||
#define TIMER_DIV(x) ((TIMER_FREQ+(x)/2)/(x))
|
||||
|
||||
#define IO_TIMER1 0x040 /* 8253 Timer #1 */
|
||||
|
||||
/*******************************************************************/
|
||||
/* Interrupt Controller */
|
||||
/*******************************************************************/
|
||||
/* these are processor defined */
|
||||
#define T_DIVIDE 0 /* divide error */
|
||||
#define T_DEBUG 1 /* debug exception */
|
||||
#define T_NMI 2 /* non-maskable interrupt */
|
||||
#define T_BRKPT 3 /* breakpoint */
|
||||
#define T_OFLOW 4 /* overflow */
|
||||
#define T_BOUND 5 /* bounds check */
|
||||
#define T_ILLOP 6 /* illegal opcode */
|
||||
#define T_DEVICE 7 /* device not available */
|
||||
#define T_DBLFLT 8 /* double fault */
|
||||
/* 9 is reserved */
|
||||
#define T_TSS 10 /* invalid task switch segment */
|
||||
#define T_SEGNP 11 /* segment not present */
|
||||
#define T_STACK 12 /* stack exception */
|
||||
#define T_GPFLT 13 /* genernal protection fault */
|
||||
#define T_PGFLT 14 /* page fault */
|
||||
/* 15 is reserved */
|
||||
#define T_FPERR 16 /* floating point error */
|
||||
#define T_ALIGN 17 /* aligment check */
|
||||
#define T_MCHK 18 /* machine check */
|
||||
#define T_DEFAULT 500 /* catchall */
|
||||
|
||||
#define INTTIMER0 0
|
||||
#define INTKEYBOARD 1
|
||||
#define INTUART0_RX 4
|
||||
|
||||
/* I/O Addresses of the two 8259A programmable interrupt controllers */
|
||||
#define IO_PIC1 0x20 /* Master(IRQs 0-7) */
|
||||
#define IO_PIC2 0xa0 /* Slave(IRQs 8-15) */
|
||||
#define IRQ_SLAVE 0x2 /* IRQ at which slave connects to master */
|
||||
#define IRQ_OFFSET 0x20 /* IRQ 0 corresponds to int IRQ_OFFSET */
|
||||
|
||||
#define MAX_HANDLERS 16 /*max number of isr handler*/
|
||||
|
||||
/*******************************************************************/
|
||||
/* CRT Register */
|
||||
/*******************************************************************/
|
||||
#define MONO_BASE 0x3b4
|
||||
#define MONO_BUF 0xb0000
|
||||
#define CGA_BASE 0x3d4
|
||||
#define CGA_BUF 0xb8000
|
||||
|
||||
#define CRT_ROWS 25
|
||||
#define CRT_COLS 80
|
||||
#define CRT_SIZE (CRT_ROWS * CRT_COLS)
|
||||
|
||||
/*******************************************************************/
|
||||
/* Keyboard Register */
|
||||
/*******************************************************************/
|
||||
#define KBSTATP 0x64 /* kbd controller status port(I) */
|
||||
#define KBS_DIB 0x01 /* kbd data in buffer */
|
||||
#define KBDATAP 0x60 /* kbd data port(I) */
|
||||
|
||||
/*******************************************************************/
|
||||
/* Serial Register */
|
||||
/*******************************************************************/
|
||||
/*Serial I/O code */
|
||||
#define COM1 0x3F8
|
||||
#define COMSTATUS 5
|
||||
#define COMDATA 0x01
|
||||
#define COMREAD 0
|
||||
#define COMWRITE 0
|
||||
|
||||
/* Bits definition of the Line Status Register (LSR)*/
|
||||
#define DR 0x01 /* Data Ready */
|
||||
#define OE 0x02 /* Overrun Error */
|
||||
#define PE 0x04 /* Parity Error */
|
||||
#define FE 0x08 /* Framing Error */
|
||||
#define BI 0x10 /* Break Interrupt */
|
||||
#define THRE 0x20 /* Transmitter Holding Register Empty */
|
||||
#define TEMT 0x40 /* Transmitter Empty */
|
||||
#define ERFIFO 0x80 /* Error receive Fifo */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BSP_H_ */
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* File : grub.h
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006, RT-Thread Develop Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://openlab.rt-thread.com/license/LICENSE
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2006-10-09 Bernard the grub related definitions
|
||||
* (multiboot)
|
||||
*/
|
||||
|
||||
#ifndef __GRUB_H__
|
||||
#define __GRUB_H__
|
||||
|
||||
/* the magic number for the multiboot header. */
|
||||
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
|
||||
|
||||
/* the flags for the multiboot header. */
|
||||
#define MULTIBOOT_HEADER_FLAGS 0x00000003
|
||||
|
||||
/* the magic number passed by a multiboot-compliant boot loader. */
|
||||
#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
|
||||
|
||||
#ifndef __ASM__
|
||||
/* the multiboot header. */
|
||||
typedef struct multiboot_header
|
||||
{
|
||||
unsigned long magic;
|
||||
unsigned long flags;
|
||||
unsigned long checksum;
|
||||
unsigned long header_addr;
|
||||
unsigned long load_addr;
|
||||
unsigned long load_end_addr;
|
||||
unsigned long bss_end_addr;
|
||||
unsigned long entry_addr;
|
||||
} multiboot_header_t;
|
||||
|
||||
/* the section header table for elf. */
|
||||
typedef struct elf_section_header_table
|
||||
{
|
||||
unsigned long num;
|
||||
unsigned long size;
|
||||
unsigned long addr;
|
||||
unsigned long shndx;
|
||||
} elf_section_header_table_t;
|
||||
|
||||
/* the multiboot information. */
|
||||
typedef struct multiboot_info
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long mem_lower;
|
||||
unsigned long mem_upper;
|
||||
unsigned long boot_device;
|
||||
unsigned long cmdline;
|
||||
unsigned long mods_count;
|
||||
unsigned long mods_addr;
|
||||
union
|
||||
{
|
||||
aout_symbol_table_t aout_sym;
|
||||
elf_section_header_table_t elf_sec;
|
||||
} u;
|
||||
unsigned long mmap_length;
|
||||
unsigned long mmap_addr;
|
||||
} multiboot_info_t;
|
||||
|
||||
/* the module structure. */
|
||||
typedef struct module
|
||||
{
|
||||
unsigned long mod_start;
|
||||
unsigned long mod_end;
|
||||
unsigned long string;
|
||||
unsigned long reserved;
|
||||
} module_t;
|
||||
|
||||
/* the memory map. be careful that the offset 0 is base_addr_low
|
||||
but no size. */
|
||||
typedef struct memory_map
|
||||
{
|
||||
unsigned long size;
|
||||
unsigned long base_addr_low;
|
||||
unsigned long base_addr_high;
|
||||
unsigned long length_low;
|
||||
unsigned long length_high;
|
||||
unsigned long type;
|
||||
} memory_map_t;
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,108 @@
|
|||
#ifndef __I386_H_
|
||||
#define __I386_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static __inline unsigned char inb(int port)
|
||||
{
|
||||
unsigned char data;
|
||||
__asm __volatile("inb %w1,%0" : "=a" (data) : "d" (port));
|
||||
return data;
|
||||
}
|
||||
|
||||
static __inline unsigned short inw(int port)
|
||||
{
|
||||
unsigned short data;
|
||||
__asm __volatile("inw %w1,%0" : "=a" (data) : "d" (port));
|
||||
return data;
|
||||
}
|
||||
|
||||
static __inline unsigned int inl(int port)
|
||||
{
|
||||
unsigned int data;
|
||||
__asm __volatile("inl %w1,%0" : "=a" (data) : "d" (port));
|
||||
return data;
|
||||
}
|
||||
|
||||
static __inline void insl(int port, void *addr, int cnt)
|
||||
{
|
||||
__asm __volatile("cld\n\trepne\n\tinsl" :
|
||||
"=D" (addr), "=c" (cnt) :
|
||||
"d" (port), "0" (addr), "1" (cnt) :
|
||||
"memory", "cc");
|
||||
}
|
||||
|
||||
static __inline void outb(int port, unsigned char data)
|
||||
{
|
||||
__asm __volatile("outb %0,%w1" : : "a" (data), "d" (port));
|
||||
}
|
||||
|
||||
static __inline void outw(int port, unsigned short data)
|
||||
{
|
||||
__asm __volatile("outw %0,%w1" : : "a" (data), "d" (port));
|
||||
}
|
||||
|
||||
/* Gate descriptors are slightly different*/
|
||||
struct Gatedesc {
|
||||
unsigned gd_off_15_0 : 16; // low 16 bits of offset in segment
|
||||
unsigned gd_ss : 16; // segment selector
|
||||
unsigned gd_args : 5; // # args, 0 for interrupt/trap gates
|
||||
unsigned gd_rsv1 : 3; // reserved(should be zero I guess)
|
||||
unsigned gd_type :4; // type(STS_{TG,IG32,TG32})
|
||||
unsigned gd_s : 1; // must be 0 (system)
|
||||
unsigned gd_dpl : 2; // descriptor(meaning new) privilege level
|
||||
unsigned gd_p : 1; // Present
|
||||
unsigned gd_off_31_16 : 16; // high bits of offset in segment
|
||||
};
|
||||
|
||||
/* Pseudo-descriptors used for LGDT, LLDT and LIDT instructions*/
|
||||
struct Pseudodesc {
|
||||
rt_uint16_t pd__garbage; // LGDT supposed to be from address 4N+2
|
||||
rt_uint16_t pd_lim; // Limit
|
||||
rt_uint32_t pd_base __attribute__ ((packed)); // Base address
|
||||
};
|
||||
|
||||
#define SETGATE(gate, istrap, sel, off, dpl) \
|
||||
{ \
|
||||
(gate).gd_off_15_0 = (rt_uint32_t) (off) & 0xffff; \
|
||||
(gate).gd_ss = (sel); \
|
||||
(gate).gd_args = 0; \
|
||||
(gate).gd_rsv1 = 0; \
|
||||
(gate).gd_type = (istrap) ? STS_TG32 : STS_IG32; \
|
||||
(gate).gd_s = 0; \
|
||||
(gate).gd_dpl = dpl; \
|
||||
(gate).gd_p = 1; \
|
||||
(gate).gd_off_31_16 = (rt_uint32_t) (off) >> 16; \
|
||||
}
|
||||
|
||||
/* Global descriptor numbers*/
|
||||
#define GD_KT 0x08 // kernel text
|
||||
#define GD_KD 0x10 // kernel data
|
||||
#define GD_UT 0x18 // user text
|
||||
#define GD_UD 0x20 // user data
|
||||
|
||||
/* Application segment type bits*/
|
||||
#define STA_X 0x8 // Executable segment
|
||||
#define STA_E 0x4 // Expand down(non-executable segments)
|
||||
#define STA_C 0x4 // Conforming code segment(executable only)
|
||||
#define STA_W 0x2 // Writeable(non-executable segments)
|
||||
#define STA_R 0x2 // Readable(executable segments)
|
||||
#define STA_A 0x1 // Accessed
|
||||
|
||||
/* System segment type bits*/
|
||||
#define STS_T16A 0x1 // Available 16-bit TSS
|
||||
#define STS_LDT 0x2 // Local Descriptor Table
|
||||
#define STS_T16B 0x3 // Busy 16-bit TSS
|
||||
#define STS_CG16 0x4 // 16-bit Call Gate
|
||||
#define STS_TG 0x5 // Task Gate / Coum Transmitions
|
||||
#define STS_IG16 0x6 // 16-bit Interrupt Gate
|
||||
#define STS_TG16 0x7 // 16-bit Trap Gate
|
||||
#define STS_T32A 0x9 // Available 32-bit TSS
|
||||
#define STS_T32B 0xb // Busy 32-bit TSS
|
||||
#define STS_CG32 0xc // 32-bit Call Gate
|
||||
#define STS_IG32 0xe // 32-bit Interrupt Gate
|
||||
#define STS_TG32 0xf // 32-bit Trap Gate
|
||||
|
||||
#endif
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* File : interrupt.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://openlab.rt-thread.com/license/LICENSE
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rthw.h>
|
||||
|
||||
#include <bsp.h>
|
||||
|
||||
extern rt_uint32_t rt_interrupt_nest;
|
||||
extern void rt_hw_idt_init(void);
|
||||
|
||||
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
|
||||
rt_uint32_t rt_thread_switch_interrput_flag;
|
||||
|
||||
/* exception and interrupt handler table */
|
||||
rt_isr_handler_t isr_table[MAX_HANDLERS];
|
||||
rt_uint16_t irq_mask_8259A = 0xFFFF;
|
||||
|
||||
/**
|
||||
* @addtogroup I386
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
* This function initializes 8259 interrupt controller
|
||||
*/
|
||||
void rt_hw_pic_init()
|
||||
{
|
||||
outb(IO_PIC1, 0x11);
|
||||
outb(IO_PIC1+1, IRQ_OFFSET);
|
||||
outb(IO_PIC1+1, 1<<IRQ_SLAVE);
|
||||
outb(IO_PIC1+1, 0x3);
|
||||
outb(IO_PIC1+1, 0xff);
|
||||
outb(IO_PIC1, 0x68);
|
||||
outb(IO_PIC1, 0x0a);
|
||||
outb(IO_PIC2, 0x11);
|
||||
outb(IO_PIC2+1, IRQ_OFFSET + 8);
|
||||
outb(IO_PIC2+1, IRQ_SLAVE);
|
||||
outb(IO_PIC2+1, 0x3);
|
||||
outb(IO_PIC2+1, 0xff);
|
||||
outb(IO_PIC2, 0x68);
|
||||
outb(IO_PIC2, 0x0a);
|
||||
|
||||
if (irq_mask_8259A != 0xFFFF)
|
||||
{
|
||||
outb(IO_PIC1+1, (char)irq_mask_8259A);
|
||||
outb(IO_PIC2+1, (char)(irq_mask_8259A >> 8));
|
||||
}
|
||||
|
||||
/* init interrupt nest, and context */
|
||||
rt_interrupt_nest = 0;
|
||||
rt_interrupt_from_thread = 0;
|
||||
rt_interrupt_to_thread = 0;
|
||||
rt_thread_switch_interrput_flag = 0;
|
||||
}
|
||||
|
||||
void rt_hw_interrupt_handle(int vector)
|
||||
{
|
||||
rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function initializes interrupt descript table and 8259 interrupt controller
|
||||
*
|
||||
*/
|
||||
void rt_hw_interrupt_init(void)
|
||||
{
|
||||
rt_hw_idt_init();
|
||||
rt_hw_pic_init();
|
||||
}
|
||||
|
||||
void rt_hw_interrupt_umask(int vector)
|
||||
{
|
||||
irq_mask_8259A = irq_mask_8259A&~(1<<vector);
|
||||
outb(IO_PIC1+1, (char)irq_mask_8259A);
|
||||
outb(IO_PIC2+1, (char)(irq_mask_8259A >> 8));
|
||||
}
|
||||
|
||||
void rt_hw_interrupt_mask(int vector)
|
||||
{
|
||||
irq_mask_8259A = irq_mask_8259A | (1<<vector);
|
||||
outb(IO_PIC1+1, (char)irq_mask_8259A);
|
||||
outb(IO_PIC2+1, (char)(irq_mask_8259A >> 8));
|
||||
}
|
||||
|
||||
void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
|
||||
{
|
||||
if(vector < MAX_HANDLERS)
|
||||
{
|
||||
if (*old_handler != RT_NULL) *old_handler = isr_table[vector];
|
||||
if (new_handler != RT_NULL) isr_table[vector] = new_handler;
|
||||
}
|
||||
}
|
||||
|
||||
rt_base_t rt_hw_interrupt_disable(void)
|
||||
{
|
||||
rt_base_t level;
|
||||
|
||||
__asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (level): :"memory");
|
||||
return level;
|
||||
}
|
||||
|
||||
void rt_hw_interrupt_enable(rt_base_t level)
|
||||
{
|
||||
__asm__ __volatile__("pushl %0 ; popfl": :"g" (level):"memory", "cc");
|
||||
}
|
||||
|
||||
/*@}*/
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* File : showmem.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006, 2008 RT-Thread Development Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://openlab.rt-thread.com/license/LICENSE
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2008-07-29 Bernard first version from QiuYi implementation
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
void rt_hw_show_memory(rt_uint32_t addr, rt_uint32_t size)
|
||||
{
|
||||
int i = 0, j =0;
|
||||
|
||||
RT_ASSERT(addr);
|
||||
|
||||
addr = addr & ~0xF;
|
||||
size = 4*((size + 3)/4);
|
||||
|
||||
while(i < size)
|
||||
{
|
||||
rt_kprintf("0x%08x: ", addr );
|
||||
|
||||
for(j=0; j<4; j++)
|
||||
{
|
||||
rt_kprintf("0x%08x ", *(rt_uint32_t *)addr);
|
||||
|
||||
addr += 4;
|
||||
i++;
|
||||
}
|
||||
|
||||
rt_kprintf("\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* File : stack.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://openlab.rt-thread.com/license/LICENSE
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#include <i386.h>
|
||||
|
||||
/**
|
||||
* @addtogroup I386
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
* This function will initialize thread stack
|
||||
*
|
||||
* @param tentry the entry of thread
|
||||
* @param parameter the parameter of entry
|
||||
* @param stack_addr the beginning stack address
|
||||
* @param texit the function will be called when thread exit
|
||||
*
|
||||
* @return stack address
|
||||
*/
|
||||
rt_uint8 *rt_hw_stack_init(void *tentry, void *parameter,
|
||||
rt_uint8 *stack_addr, void *texit)
|
||||
{
|
||||
unsigned long *stk;
|
||||
|
||||
stk = (unsigned long *)stack_addr;
|
||||
*(--stk) = (unsigned long)parameter;
|
||||
*(--stk) = (unsigned long)texit;
|
||||
*(--stk) = 0x200; /*flags*/
|
||||
*(--stk) = 0x08; /*cs*/
|
||||
*(--stk) = (unsigned long)tentry; /*eip*/
|
||||
*(--stk) = 0; /*irqno*/
|
||||
*(--stk) = 0x10; /*ds*/
|
||||
*(--stk) = 0x10; /*es*/
|
||||
*(--stk) = 0; /*eax*/
|
||||
*(--stk) = 0; /*ecx*/
|
||||
*(--stk) = 0; /*edx*/
|
||||
*(--stk) = 0; /*ebx*/
|
||||
*(--stk) = 0; /*esp*/
|
||||
*(--stk) = 0; /*ebp*/
|
||||
*(--stk) = 0; /*esi*/
|
||||
*(--stk) = 0; /*edi*/
|
||||
|
||||
/* return task's current stack address */
|
||||
return (rt_uint8 *)stk;
|
||||
}
|
||||
/*@}*/
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* File : start.S
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://openlab.rt-thread.com/license/LICENSE
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2006-09-15 QiuYi The first version
|
||||
*/
|
||||
|
||||
#define __ASM__
|
||||
#include <grub.h>
|
||||
|
||||
#define CONFIG_STACKSIZE 8192
|
||||
|
||||
/**
|
||||
* @addtogroup I386
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
.section .init, "ax"
|
||||
.text
|
||||
|
||||
/* the system entry */
|
||||
.globl _start
|
||||
_start:
|
||||
jmp multiboot_entry
|
||||
|
||||
/* Align 32 bits boundary. */
|
||||
.align 4
|
||||
|
||||
/* multiboot header. */
|
||||
multiboot_header:
|
||||
/* magic */
|
||||
.long MULTIBOOT_HEADER_MAGIC
|
||||
/* flags */
|
||||
.long MULTIBOOT_HEADER_FLAGS
|
||||
/* checksum */
|
||||
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
|
||||
|
||||
multiboot_entry:
|
||||
movl $(_end + 0x1000),%esp
|
||||
|
||||
/* reset eflags. */
|
||||
pushl $0
|
||||
popf
|
||||
|
||||
/*rebuild globe describe table*/
|
||||
lgdt mygdtdesc
|
||||
|
||||
movl $0x10,%eax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
movw %ax,%ss
|
||||
ljmp $0x08, $relocated
|
||||
|
||||
relocated:
|
||||
/* push the pointer to the multiboot information structure. */
|
||||
pushl %ebx
|
||||
|
||||
/* push the magic value. */
|
||||
pushl %eax
|
||||
|
||||
call rtthread_startup
|
||||
|
||||
/* never get here */
|
||||
spin:
|
||||
hlt
|
||||
jmp spin
|
||||
|
||||
.data
|
||||
.p2align 2
|
||||
mygdt:
|
||||
.word 0,0,0,0
|
||||
|
||||
.word 0x07FF /* 8Mb - limit=2047 */
|
||||
.word 0x0000
|
||||
.word 0x9A00 /* code read/exec */
|
||||
.word 0x00C0
|
||||
|
||||
.word 0x07FF /* 8Mb - limit=2047 */
|
||||
.word 0x0000
|
||||
.word 0x9200 /* data read/write */
|
||||
.word 0x00C0
|
||||
|
||||
mygdtdesc:
|
||||
.word 0x17
|
||||
.long mygdt
|
||||
|
||||
/*@}*/
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* File : trap.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://openlab.rt-thread.com/license/LICENSE
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rthw.h>
|
||||
|
||||
#include <bsp.h>
|
||||
|
||||
/* Interrupt descriptor table. (Must be built at run time because
|
||||
* shifted function addresses can't be represented in relocation records.)
|
||||
*/
|
||||
struct Gatedesc idt[256] = { {0}, };
|
||||
struct Pseudodesc idt_pd =
|
||||
{
|
||||
0, sizeof(idt) - 1, (unsigned long) idt,
|
||||
};
|
||||
|
||||
/* exception and interrupt handler table */
|
||||
extern rt_isr_handler_t isr_table[];
|
||||
extern rt_isr_handler_t trap_func[];
|
||||
extern rt_isr_handler_t hdinterrupt_func[];
|
||||
|
||||
/**
|
||||
* @addtogroup I386
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
/**
|
||||
* this function initializes the interrupt descript table
|
||||
*
|
||||
*/
|
||||
void rt_hw_idt_init(void)
|
||||
{
|
||||
extern void Xdefault;
|
||||
int i, j, func;
|
||||
|
||||
for(i=0; i<MAX_HANDLERS; i++)
|
||||
{
|
||||
isr_table[i] = rt_hw_interrupt_handle;
|
||||
}
|
||||
|
||||
// install a default handler
|
||||
for (i = 0; i < sizeof(idt)/sizeof(idt[0]); i++)
|
||||
SETGATE(idt[i], 0, GD_KT, &Xdefault, 0);
|
||||
|
||||
/*install trap handler*/
|
||||
for(i = 0; i < 16; i++)
|
||||
{
|
||||
func = (int)trap_func[i];
|
||||
SETGATE(idt[i], 0, GD_KT, func, 0);
|
||||
}
|
||||
|
||||
func = (int)trap_func[3];
|
||||
SETGATE(idt[3], 0, GD_KT, func, 3);
|
||||
|
||||
i = 0;
|
||||
|
||||
/*install exteral interrupt handler*/
|
||||
for(j = IRQ_OFFSET; j < IRQ_OFFSET + MAX_HANDLERS; j++)
|
||||
{
|
||||
func = (int)hdinterrupt_func[i];
|
||||
SETGATE(idt[j], 0, GD_KT, func, 0);
|
||||
i++;
|
||||
}
|
||||
|
||||
// Load the IDT
|
||||
asm volatile("lidt idt_pd + 2");
|
||||
}
|
||||
|
||||
/**
|
||||
* this function will deal with all kinds of kernel trap
|
||||
*
|
||||
*@param trapno the trap number
|
||||
*
|
||||
*/
|
||||
void rt_hw_trap_irq(int trapno)
|
||||
{
|
||||
switch(trapno)
|
||||
{
|
||||
case T_DIVIDE:
|
||||
rt_kprintf("Divide error interrupt\n");
|
||||
RT_ASSERT(0);
|
||||
case T_PGFLT:
|
||||
rt_kprintf("Page fault interrupt\n");
|
||||
RT_ASSERT(0);
|
||||
case T_GPFLT:
|
||||
rt_kprintf("General protection interrupt\n");
|
||||
RT_ASSERT(0);
|
||||
case T_DEFAULT:
|
||||
rt_hw_interrupt_handle(T_DEFAULT);
|
||||
return;
|
||||
}
|
||||
|
||||
/*kernel bug if run here*/
|
||||
RT_ASSERT(0);
|
||||
}
|
||||
|
||||
/*@}*/
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* File : trapisr.S
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006, RT-Thread Development Team
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://openlab.rt-thread.com/license/LICENSE
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup I386
|
||||
*/
|
||||
/*@{*/
|
||||
|
||||
#define ENTRY(proc)\
|
||||
.align 2;\
|
||||
.globl proc;\
|
||||
.type proc,@function;\
|
||||
proc:
|
||||
#define TRAPFNC(name,num)\
|
||||
ENTRY(name)\
|
||||
pushl $(num);\
|
||||
jmp _traps;\
|
||||
.data;\
|
||||
.long name;\
|
||||
.text
|
||||
#define TRAPFNC_NOEC(name,num)\
|
||||
ENTRY(name)\
|
||||
pushl $0;\
|
||||
pushl $(num);\
|
||||
jmp _traps;\
|
||||
.data;\
|
||||
.long name;\
|
||||
.text
|
||||
|
||||
.globl trap_func
|
||||
.data
|
||||
.align 4
|
||||
.type trap_func,@object
|
||||
trap_func :
|
||||
.text
|
||||
|
||||
/* CPU traps */
|
||||
TRAPFNC_NOEC(Xdivide, 0)
|
||||
TRAPFNC_NOEC(Xdebug, 1)
|
||||
TRAPFNC_NOEC(Xnmi, 2)
|
||||
TRAPFNC_NOEC(Xbrkpt, 3)
|
||||
TRAPFNC_NOEC(Xoflow, 4)
|
||||
TRAPFNC_NOEC(Xbound, 5)
|
||||
TRAPFNC_NOEC(Xillop, 6)
|
||||
TRAPFNC_NOEC(Xdevice, 7)
|
||||
TRAPFNC (Xdblflt, 8)
|
||||
TRAPFNC (Xtss, 9)
|
||||
TRAPFNC (Xsegnp, 10)
|
||||
TRAPFNC (Xstack, 11)
|
||||
TRAPFNC (Xgpflt, 12)
|
||||
TRAPFNC (Xpgflt, 13)
|
||||
TRAPFNC_NOEC(Xfperr, 14)
|
||||
TRAPFNC (Xalign, 15)
|
||||
|
||||
/* default handler -- not for any specific trap */
|
||||
TRAPFNC (Xdefault, 500)
|
||||
|
||||
.p2align 4,0x90
|
||||
.globl _traps
|
||||
.type _traps,@function
|
||||
.globl rt_interrupt_enter
|
||||
.globl rt_interrupt_leave
|
||||
|
||||
_traps:
|
||||
push %ds
|
||||
push %es
|
||||
pushal
|
||||
movw $0x10,%ax
|
||||
movw %ax,%ds
|
||||
movw %ax,%es
|
||||
pushl %esp
|
||||
call rt_interrupt_enter
|
||||
movl %esp, %eax
|
||||
addl $0x2c,%eax /*get trapno*/
|
||||
movl (%eax),%eax
|
||||
pushl %eax /*push trapno*/
|
||||
call rt_hw_trap_irq
|
||||
addl $4,%esp
|
||||
call rt_interrupt_leave
|
||||
popl %esp
|
||||
popal
|
||||
pop %es
|
||||
pop %ds
|
||||
add $8,%esp
|
||||
iret
|
||||
|
||||
/*@}*/
|
Loading…
Reference in New Issue