原始版本

This commit is contained in:
冯佳
2025-06-19 21:56:46 +08:00
parent fe98e5f010
commit a4841450cf
4152 changed files with 1910684 additions and 0 deletions

View File

@ -0,0 +1,13 @@
# RT-Thread building script for component
from building import *
Import('rtconfig')
cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
CPPPATH = [cwd]
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
Return('group')

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2006-10-09 Bernard the first version for i386
*/
#include <stdint.h>
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;
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2006-10-09 Bernard the first version for i386
*/
#include <stdint.h>
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;
}

View File

@ -0,0 +1,81 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* 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*/
/*
* add by ssslady@gmail.com 2009-10-14
* When we return again the esp should no be change.
* The old code change the esp to esp-4 :-(.
* A protection fault maybe occure for img created by some compiler,eg.gcc in the fedor-11
* -------------------------------------------------------------------------
* entry old code new code
* EIP ->return esp EIP FLAGS ->return esp
* ... FLAGS ->retern esp CS
* CS EIP
* EIP
*/
popl %eax /*get flags*/
popl %ebx /*get eip*/
pushl %eax /*push flags*/
push %cs /*push cs*/
pushl %ebx /*push eip*/
/*-------------------------------------------------------------------
*/
/*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 0x3c(%esp), %eax /*to thread TCB*/
movl 0x38(%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

View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021/02/19 Bernard Implement rt_hw_context_switch_interrupt in C
*/
#include <rthw.h>
#include <rtthread.h>
volatile rt_ubase_t rt_interrupt_from_thread = 0;
volatile rt_ubase_t rt_interrupt_to_thread = 0;
volatile rt_uint32_t rt_thread_switch_interrupt_flag = 0;
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");
}
void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to, rt_thread_t from_thread, rt_thread_t to_thread)
{
if (rt_thread_switch_interrupt_flag == 0)
rt_interrupt_from_thread = from;
rt_interrupt_to_thread = to;
rt_thread_switch_interrupt_flag = 1;
return ;
}
/**
* 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_t *rt_hw_stack_init(void *tentry, void *parameter,
rt_uint8_t *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_t *)stk;
}

View File

@ -0,0 +1,118 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2006-09-15 QiuYi The first version
*/
/**
* @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 rt_hw_isr
.globl rt_thread_switch_interrupt_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 /* copy esp to eax */
addl $0x2c, %eax /* move to vector address */
movl (%eax), %eax /* vector(eax) = *eax */
pushl %eax /* push argument : int vector */
call rt_hw_isr
add $4, %esp /* restore argument */
call rt_interrupt_leave
/* if rt_thread_switch_interrupt_flag set, jump to _interrupt_thread_switch and don't return */
movl $rt_thread_switch_interrupt_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
/*@}*/

View File

@ -0,0 +1,131 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2015/9/15 Bernard Update to new interrupt framework.
*/
#include <rthw.h>
#include <rtthread.h>
#include <bsp.h>
extern void rt_hw_idt_init(void);
/* exception and interrupt handler table */
struct rt_irq_desc irq_desc[MAX_HANDLERS];
rt_uint16_t irq_mask_8259A = 0xFFFF;
void rt_hw_interrupt_handle(int vector, void* param);
/**
* @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));
}
}
void rt_hw_interrupt_handle(int vector, void* param)
{
rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
}
void rt_hw_isr(int vector)
{
if (vector < MAX_HANDLERS)
{
irq_desc[vector].handler(vector, irq_desc[vector].param);
}
}
/**
* This function initializes interrupt descript table and 8259 interrupt controller
*
*/
void rt_hw_interrupt_init(void)
{
int idx;
rt_hw_idt_init();
rt_hw_pic_init();
/* init exceptions table */
for(idx=0; idx < MAX_HANDLERS; idx++)
{
irq_desc[idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle;
irq_desc[idx].param = RT_NULL;
#ifdef RT_USING_INTERRUPT_INFO
rt_snprintf(irq_desc[idx].name, RT_NAME_MAX - 1, "default");
irq_desc[idx].counter = 0;
#endif
}
}
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));
}
rt_isr_handler_t rt_hw_interrupt_install(int vector,
rt_isr_handler_t handler,
void *param,
const char *name)
{
rt_isr_handler_t old_handler = RT_NULL;
if(vector < MAX_HANDLERS)
{
old_handler = irq_desc[vector].handler;
if (handler != RT_NULL)
{
irq_desc[vector].handler = (rt_isr_handler_t)handler;
irq_desc[vector].param = param;
#ifdef RT_USING_INTERRUPT_INFO
rt_snprintf(irq_desc[vector].name, RT_NAME_MAX - 1, "%s", name);
irq_desc[vector].counter = 0;
#endif
}
}
return old_handler;
}
/*@}*/

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2006-09-15 QiuYi The first version.
* 2012-02-15 aozima update.
*/
/* the magic number for the multiboot header. */
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
/* the flags for the multiboot header. */
#define MULTIBOOT_HEADER_FLAGS 0x00000003
#define CONFIG_STACKSIZE 8192
/**
* @addtogroup I386
*/
/*@{*/
.section .init, "ax"
/* 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 __gdtdesc
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
__gdt:
.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
__gdtdesc:
.word 0x17
.long __gdt
/*@}*/

View File

@ -0,0 +1,100 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include <rthw.h>
#include <rtthread.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[];
extern void rt_hw_interrupt_handle(int vector, void* param);
/**
* @addtogroup I386
*/
/*@{*/
/**
* this function initializes the interrupt descript table
*
*/
void rt_hw_idt_init(void)
{
extern void Xdefault(void);
int i, j, func;
// 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, RT_NULL);
return;
}
/*kernel bug if run here*/
RT_ASSERT(0);
}
/*@}*/

View File

@ -0,0 +1,96 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2006-09-15 QiuYi The first version.
*/
/**
* @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
/*@}*/