1
0
Эх сурвалжийг харах

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
bernard.xiong 16 жил өмнө
parent
commit
1d74273319

+ 49 - 0
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;
+}

+ 49 - 0
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;
+}

+ 20 - 0
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 */
+}

+ 89 - 0
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

+ 118 - 0
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
+
+/*@}*/

+ 125 - 0
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_ */

+ 93 - 0
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

+ 108 - 0
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

+ 118 - 0
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");
+}
+
+/*@}*/

+ 42 - 0
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;
+}

+ 59 - 0
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;
+}
+/*@}*/

+ 94 - 0
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
+
+/*@}*/

+ 108 - 0
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);
+}
+
+/*@}*/

+ 97 - 0
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
+
+/*@}*/