summaryrefslogtreecommitdiff
path: root/libcpu
diff options
context:
space:
mode:
Diffstat (limited to 'libcpu')
-rw-r--r--libcpu/ia32/__udivsi3.c49
-rw-r--r--libcpu/ia32/__umodsi3.c49
-rw-r--r--libcpu/ia32/backtrace.c20
-rw-r--r--libcpu/ia32/context.S89
-rw-r--r--libcpu/ia32/hdisr.S118
-rw-r--r--libcpu/ia32/include/bsp.h125
-rw-r--r--libcpu/ia32/include/grub.h93
-rw-r--r--libcpu/ia32/include/i386.h108
-rw-r--r--libcpu/ia32/interrupt.c118
-rw-r--r--libcpu/ia32/showmem.c42
-rw-r--r--libcpu/ia32/stack.c59
-rw-r--r--libcpu/ia32/start.S94
-rw-r--r--libcpu/ia32/trap.c108
-rw-r--r--libcpu/ia32/trapisr.S97
14 files changed, 1169 insertions, 0 deletions
diff --git a/libcpu/ia32/__udivsi3.c b/libcpu/ia32/__udivsi3.c
new file mode 100644
index 0000000000..dfcf5325ff
--- /dev/null
+++ b/libcpu/ia32/__udivsi3.c
@@ -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;
+}
diff --git a/libcpu/ia32/__umodsi3.c b/libcpu/ia32/__umodsi3.c
new file mode 100644
index 0000000000..2bb0c677b7
--- /dev/null
+++ b/libcpu/ia32/__umodsi3.c
@@ -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;
+}
diff --git a/libcpu/ia32/backtrace.c b/libcpu/ia32/backtrace.c
new file mode 100644
index 0000000000..d7a152469b
--- /dev/null
+++ b/libcpu/ia32/backtrace.c
@@ -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 */
+}
diff --git a/libcpu/ia32/context.S b/libcpu/ia32/context.S
new file mode 100644
index 0000000000..96ebda41cf
--- /dev/null
+++ b/libcpu/ia32/context.S
@@ -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
diff --git a/libcpu/ia32/hdisr.S b/libcpu/ia32/hdisr.S
new file mode 100644
index 0000000000..b16311641d
--- /dev/null
+++ b/libcpu/ia32/hdisr.S
@@ -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
+
+/*@}*/
diff --git a/libcpu/ia32/include/bsp.h b/libcpu/ia32/include/bsp.h
new file mode 100644
index 0000000000..e14e589274
--- /dev/null
+++ b/libcpu/ia32/include/bsp.h
@@ -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_ */
diff --git a/libcpu/ia32/include/grub.h b/libcpu/ia32/include/grub.h
new file mode 100644
index 0000000000..18d08a78ad
--- /dev/null
+++ b/libcpu/ia32/include/grub.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
diff --git a/libcpu/ia32/include/i386.h b/libcpu/ia32/include/i386.h
new file mode 100644
index 0000000000..4b5a0e7bd0
--- /dev/null
+++ b/libcpu/ia32/include/i386.h
@@ -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
diff --git a/libcpu/ia32/interrupt.c b/libcpu/ia32/interrupt.c
new file mode 100644
index 0000000000..fe0bf07a58
--- /dev/null
+++ b/libcpu/ia32/interrupt.c
@@ -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");
+}
+
+/*@}*/
diff --git a/libcpu/ia32/showmem.c b/libcpu/ia32/showmem.c
new file mode 100644
index 0000000000..c171a9bcd7
--- /dev/null
+++ b/libcpu/ia32/showmem.c
@@ -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;
+}
diff --git a/libcpu/ia32/stack.c b/libcpu/ia32/stack.c
new file mode 100644
index 0000000000..3efaf3f240
--- /dev/null
+++ b/libcpu/ia32/stack.c
@@ -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;
+}
+/*@}*/
diff --git a/libcpu/ia32/start.S b/libcpu/ia32/start.S
new file mode 100644
index 0000000000..612ed3ea10
--- /dev/null
+++ b/libcpu/ia32/start.S
@@ -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
+
+/*@}*/
diff --git a/libcpu/ia32/trap.c b/libcpu/ia32/trap.c
new file mode 100644
index 0000000000..10595dc5a1
--- /dev/null
+++ b/libcpu/ia32/trap.c
@@ -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);
+}
+
+/*@}*/
diff --git a/libcpu/ia32/trapisr.S b/libcpu/ia32/trapisr.S
new file mode 100644
index 0000000000..c84cebebc7
--- /dev/null
+++ b/libcpu/ia32/trapisr.S
@@ -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
+
+/*@}*/