📄 os_cpu_c.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 + -