⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_cpu_c.c

📁 一个uC/OS-II的simplest edition
💻 C
字号:

#include <stdio.h>
#include "includes.h"


/*
 ***************************************************************************************
 *                                      GLOBALs
 ***************************************************************************************
 */
IDT_DESC	idt_desc;
GATE		idt[MAX_IDT_ENTRIES];		/* (00h-19h) Reserved for CPU interrupts */
						/* (20h-2Fh) Reserved for IRQ interrupts */
						/* (30h-3Fh) Reserved for OS interrupts  */


/* exception strings */
/* GLOBAL */
static char *const exception_strings[] = {
	"#DE Divide Error",
	"#DB Debug",
	"-- NMI Interrupt",
	"#BP Breakpoint",
	"#OF Overflow",
	"BR BOUND Range Exceeded",
	"#UD Invalid Opcode(Undefined Opcode)",
	"#NM Device Not Available(No Math Coprocessor)",
	"#DF Double Fault",
	"-- Coprocessor Segment Overrun(reserved)",
	"#TS Invalid TSS",
	"#NP Segment Not Present",
	"#SS Stack-Segment Fault",
	"#GP General Protection",
	"#PF Page Fault",
	"-- (Intel reserved. Don't use.)",
	"#MF Floating-Point Error(Math Fault)",
	"#AC Alignment Check",
	"#MC Machine Check",
	"#XF Streaming SIMD Extensions"
};


/*
 ***************************************************************************************
 *                                     PROTOTYPEs
 ***************************************************************************************
 */

static void	Init8259A(void);
static void	InitIDT(void);

static void	SetIntVector( int IntNo, void * Offset );
static void	SetIDTGate( int IntNo, INT16U Type, INT16U Selector, INT32U Offset );

static void	Dummy_Func(void);	/* Task return addr */


/*
 ***************************************************************************************
 *                                     FUNCTIONs
 ***************************************************************************************
 */


/*======================================================================*
                            OSCpuInit()
 *----------------------------------------------------------------------*
 初始化 CPU
 *======================================================================*/
void	OSCpuInit(void)
{
	idt_desc.base  = (INT32U)&idt[0];
	idt_desc.limit = (INT16U)(sizeof(GATE) * MAX_IDT_ENTRIES - 1);
	
	Init8259A();
	InitIDT();
}


/*======================================================================*
                            OSTaskStkInit
 *----------------------------------------------------------------------*
 初始化 task stack
 *======================================================================*/
OS_STK *	OSTaskStkInit(void (*task)(void *pd), void *pdata, OS_STK *ptos)
{
	OS_STK*	stk;

	stk = (OS_STK *) ptos;			/* Load stack pointer					*/

	*stk-- = (INT32U) pdata;		/* Simulate a function call (to pass the parameter)	*/
	*stk-- = Dummy_Func;

	*stk-- = 0x1202;			/* IF=1, IOPL=1, bit 2 is always 1.			*/
	*stk-- = CS_SELECTOR;
	*stk-- = (INT32U) task;			/* Entry point						*/

	*stk-- = 0;						// EAX
	*stk-- = 0;						// ECX
	*stk-- = 0;						// EDX
	*stk-- = 0;						// EBX
	*stk-- = 0;						// ESP (unused)
	*stk-- = 0;						// EBP
	*stk-- = 0;						// ESI
	*stk   = 0;						// EDI
	
	
	return stk;
}

/*======================================================================*
                            Dummy_Func()
 *----------------------------------------------------------------------*
 When a task returns, eip goes here
 *======================================================================*/
static void	Dummy_Func(void)
{
	/* do nothing */
	while (1)
		;
}

/*======================================================================*
                            Init8259A()
 *----------------------------------------------------------------------*
 初始化 8259
 *======================================================================*/
static void	Init8259A(void)
{
	out_byte(I8259_MASTER_0, 0x11);			/* Master 8259, ICW1. */
	out_byte(I8259_SLAVE_0,	 0x11);			/* Slave  8259, ICW1. */
	out_byte(I8259_MASTER_1, INT_VECTOR_IRQ0);	/* Master 8259, ICW2. 设置 '主8259' 的中断入口地址为 0x20. */
	out_byte(I8259_SLAVE_1,  INT_VECTOR_IRQ8);	/* Slave  8259, ICW2. 设置 '从8259' 的中断入口地址为 0x28  */
	out_byte(I8259_MASTER_1, 0x4);			/* Master 8259, ICW3. IR2 对应 '从8259'.    */
	out_byte(I8259_SLAVE_1,  0x2);			/* Slave  8259, ICW3. 对应 '主8259' 的 IR2. */
	out_byte(I8259_MASTER_1, 0x1);			/* Master 8259, ICW4. */
	out_byte(I8259_SLAVE_1,  0x1);			/* Slave  8259, ICW4. */

	out_byte(I8259_MASTER_1, 0xFE);			/* Master 8259, OCW1. */
	out_byte(I8259_SLAVE_1,	 0xFF);			/* Slave  8259, OCW1. */
}



/*======================================================================*
                            InitIDT()
 *----------------------------------------------------------------------*
 初始化 IDT
 *======================================================================*/

/* 中断处理函数 */
void	divide_error();
void	debug();
void	nmi();
void	breakpoint();
void	overflow();
void	bounds_check();
void	inval_opcode();
void	copr_not_available();
void	double_fault();
void	copr_seg_overrun();
void	inval_tss();
void	segment_not_present();
void	stack_exception();
void	general_protection();
void	page_fault();
void	intel_reserved();
void	copr_error();
void	alignment_check();
void	machine_check();
void	simd_fp_exception();
void	OSTickISR();
void	hwint01();
void	hwint02();
void	hwint03();
void	hwint04();
void	hwint05();
void	hwint06();
void	hwint07();
void	hwint08();
void	hwint09();
void	hwint10();
void	hwint11();
void	hwint12();
void	hwint13();
void	hwint14();
void	hwint15();

static	void	InitIDT(void)
{
	/* 全部初始化成中断门(没有陷阱门) */
	/* 0 ~ 19 system exception */
	SetIntVector(  0,   divide_error );
	SetIntVector(  1,   debug );
	SetIntVector(  2,   nmi );
	SetIntVector(  3,   breakpoint );
	SetIntVector(  4,   overflow );
	SetIntVector(  5,   bounds_check );
	SetIntVector(  6,   inval_opcode );
	SetIntVector(  7,   copr_not_available );
	SetIntVector(  8,   double_fault );
	SetIntVector(  9,   copr_seg_overrun );
	SetIntVector( 10,   inval_tss );
	SetIntVector( 11,   segment_not_present );
	SetIntVector( 12,   stack_exception );
	SetIntVector( 13,   general_protection );
	SetIntVector( 14,   page_fault );
	SetIntVector( 15,   intel_reserved );
	SetIntVector( 16,   copr_error );
	SetIntVector( 17,   alignment_check );
	SetIntVector( 18,   machine_check );
	SetIntVector( 19,   simd_fp_exception );
	
	/* 20 ~ 31 Intel reserved */
	SetIntVector( 20,   intel_reserved );
	SetIntVector( 21,   intel_reserved );
	SetIntVector( 22,   intel_reserved );
	SetIntVector( 23,   intel_reserved );
	SetIntVector( 24,   intel_reserved );
	SetIntVector( 25,   intel_reserved );
	SetIntVector( 26,   intel_reserved );
	SetIntVector( 27,   intel_reserved );
	SetIntVector( 28,   intel_reserved );
	SetIntVector( 29,   intel_reserved );
	SetIntVector( 30,   intel_reserved );
	SetIntVector( 31,   intel_reserved );
	SetIntVector( INT_VECTOR_IRQ0 + 0,   OSTickISR );
	SetIntVector( INT_VECTOR_IRQ0 + 1,   hwint01 );
	SetIntVector( INT_VECTOR_IRQ0 + 2,   hwint02 );
	SetIntVector( INT_VECTOR_IRQ0 + 3,   hwint03 );
	SetIntVector( INT_VECTOR_IRQ0 + 4,   hwint04 );
	SetIntVector( INT_VECTOR_IRQ0 + 5,   hwint05 );
	SetIntVector( INT_VECTOR_IRQ0 + 6,   hwint06 );
	SetIntVector( INT_VECTOR_IRQ0 + 7,   hwint07 );
	SetIntVector( INT_VECTOR_IRQ8 + 0,   hwint08 );
	SetIntVector( INT_VECTOR_IRQ8 + 1,   hwint09 );
	SetIntVector( INT_VECTOR_IRQ8 + 2,   hwint10 );
	SetIntVector( INT_VECTOR_IRQ8 + 3,   hwint11 );
	SetIntVector( INT_VECTOR_IRQ8 + 4,   hwint12 );
	SetIntVector( INT_VECTOR_IRQ8 + 5,   hwint13 );
	SetIntVector( INT_VECTOR_IRQ8 + 6,   hwint14 );
	SetIntVector( INT_VECTOR_IRQ8 + 7,   hwint15 );
	
	/* OS int handler */
	SetIntVector( INT_CTX_SW, OSCtxSw );
	
	// fprintf( stderr, "OSTickISR: 0x%x\n", OSTickISR );
}


/*======================================================================*
                             SetIntVector()
 *----------------------------------------------------------------------*
 
 *======================================================================*/
static	void	SetIntVector( int IntNo, void * Offset )
{
	SetIDTGate(IntNo, IDTGATE_INT, CS_SELECTOR, (INT32U) Offset);
}


/*======================================================================*
                             SetIDTGate()
 *----------------------------------------------------------------------*
 
 *======================================================================*/
static	void	SetIDTGate( int IntNo, INT16U Type, INT16U Selector, INT32U Offset )
{
	GATE *	pGate	= &idt[IntNo];

	pGate->offset_low	= (INT16U) (Offset & 0xffff);
	pGate->offset_high	= (INT16U) (Offset >> 16);
	pGate->selector		= Selector;
	pGate->type		= Type;
}




/*======================================================================*
  exception_handler( INT32U vector_no, INT32U err_code, INT32U eip, INT32U cs, INT32U eflags )
 *----------------------------------------------------------------------*
  common exception handler
 *======================================================================*/
void exception_handler( INT32U vector_no, INT32U err_code, INT32U eip, INT32U cs, INT32U eflags )
{
	fprintf( stderr, "#%2d - %s\n", vector_no, exception_strings[vector_no] );
	fprintf( stderr, "EIP: 0x%08x;    CS: 0x%04x;    EFLAGS: 0x%08x;\n", eip, cs, eflags );
	
	if ( err_code != 0xFFFFFFFF )
	{
		fprintf( stderr, "error code: %d\n", err_code );
	}
}

/*======================================================================*
                       irq_handler( INT32U irq )
 *----------------------------------------------------------------------*
  common irq handler
 *======================================================================*/
void irq_handler( INT32U irq )
{
	static char *const msg = "irq: 000\n";
	int i = 7;
	
	while (irq%10 != 0)
	{
		msg[i--]  = (char)((irq % 10) + '0');
		irq      /= 10;
	}
	
	write( 0, msg, 9 );
	
	// fprintf( stderr, "irq: 0x%x\n", irq );
}

/*======================================================================*
                   write(int file, char *ptr, int len)
 *----------------------------------------------------------------------*
  helper func for 'newlib'
 *======================================================================*/
int
write(int file, char *ptr, int len)
{
	static short *p = (short *)0xb8000;
	int i;

	for(i = 0; i < len; i++) {
		switch(*ptr) {
		case '\n':
		case '\r':
			p = p - (((int)p - 0xb8000) % 160)/2;
			if(*ptr == '\n') {
				p += 80;
			}
			break;
		case '\t':
			p += 8 - ((((int)p - 0xB8000) % 160) % 16)/2;
			break;
		case '\b':
			p--;
			break;
		default:
			*p++ = (0xf << 8) | (*ptr);
			break;
		}
		ptr++;
		if(p >= (short *)0xb8fa0)
			p = (short *)0xb8000;
	}

	return len;
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -