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 + +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 + +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 + +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 + +/*******************************************************************/ +/* 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 +#include + +#include + +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<> 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<> 8)); +} + +void rt_hw_interrupt_mask(int vector) +{ + irq_mask_8259A = irq_mask_8259A | (1<> 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 + +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 + +#include + +/** + * @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 + +#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 +#include + +#include + +/* 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