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

📄 cpu.h

📁 微内核软实时操作系统
💻 H
字号:
/* * Copyright (c) 2005, Kohsuke Ohtani * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. Neither the name of the author nor the names of any co-contributors  *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef _CPU_H#define _CPU_H/* * GDTs */#define KERNEL_CS	0x10#define KERNEL_DS	0x18#define USER_CS		0x20#define USER_DS		0x28#define KERNEL_TSS	0x38#define NR_GDT		8/* * IDTs */#define NR_IDT		0x41#define SYSCALL_INT	0x40#define INVALID_INT	0xFF#ifndef __ASSEMBLY__/* * Segment Descriptor */struct seg_desc {	int limit_lo:16;	/* segment limit (lsb) */	int base_lo:24;		/* segment base address (lsb) */	int type:8;		/* type */	int limit_hi:4;		/* segment limit (msb) */	int size:4;		/* size */	int base_hi:8;		/* segment base address (msb) */} __attribute__ ((packed));/* * Gate Descriptor */struct gate_desc {	int offset_lo:16;	/* gate offset (lsb) */	int selector:16;	/* gate segment selector */	int nr_copy:8;		/* stack copy count */	int type:8;		/* type */	int offset_hi:16;	/* gate offset (msb) */} __attribute__ ((packed));/* * Linear memory description for lgdt and lidt instructions. */struct desc_p {	u_short limit;	u_long base;} __attribute__ ((packed));/* * Segment size */#define SIZE_32		0x4	/* 32-bit segment */#define SIZE_16		0x0	/* 16-bit segment */#define SIZE_4K		0x8	/* 4K limit field *//* * Segment type */#define ST_ACC		0x01	/* accessed */#define ST_LDT		0x02	/* LDT */#define ST_CALL_GATE_16	0x04	/* 16-bit call gate */#define ST_TASK_GATE	0x05	/* task gate */#define ST_TSS		0x09	/* task segment */#define ST_CALL_GATE	0x0c	/* call gate */#define ST_INTR_GATE	0x0e	/* interrupt gate */#define ST_TRAP_GATE	0x0f	/* trap gate */#define ST_TSS_BUSY	0x02	/* task busy */#define ST_DATA		0x10	/* data */#define ST_DATA_W	0x12	/* data, writable */#define ST_DATA_E	0x14	/* data, expand-down */#define ST_DATA_EW	0x16	/* data, expand-down, writable */#define ST_CODE		0x18	/* code */#define ST_CODE_R	0x1a	/* code, readable */#define ST_CODE_C	0x1c	/* code, conforming */#define ST_CODE_CR	0x1e	/* code, conforming, readable */#define ST_KERN		0x00	/* kernel access only */#define ST_USER		0x60	/* user access */#define ST_PRESENT	0x80	/* segment present *//* * Task State Segment (TSS) */#define IO_BITMAP_SIZE		(65536/8 + 1)#define INVALID_IO_BITMAP	0x8000struct tss {	u_long back_link;	u_long esp0, ss0;	u_long esp1, ss1;	u_long esp2, ss2;	u_long cr3;	u_long eip;	u_long eflags;	u_long eax, ecx, edx, ebx;	u_long esp, ebp, esi, edi;	u_long es, cs, ss, ds, fs, gs;	u_long ldt;	u_short dbg_trace;	u_short io_bitmap_offset;#if 0	u_long io_bitmap[IO_BITMAP_SIZE/4+1];	u_long pad[5];#endif} __attribute__ ((packed));/* * i386 flags register */#define EFL_CF		0x00000001	/* Carry */#define EFL_PF		0x00000004	/* Parity */#define EFL_AF		0x00000010	/* Carry */#define EFL_ZF		0x00000040	/* Zero */#define EFL_SF		0x00000080	/* Sign */#define EFL_TF		0x00000100	/* Trap */#define EFL_IF		0x00000200	/* Interrupt enable */#define EFL_DF		0x00000400	/* Direction */#define EFL_OF		0x00000800	/* Overflow */#define EFL_IOPL	0x00003000	/* IO privilege level: */#define EFL_IOPL_KERN	0x00000000	/* Kernel */#define EFL_IOPL_USER	0x00003000	/* User */#define EFL_NT		0x00004000	/* Nested task */#define EFL_RF		0x00010000	/* Resume without tracing */#define EFL_VM		0x00020000	/* Virtual 8086 mode */#define EFL_AC		0x00040000	/* Alignment Check *//* * CR0 register */#define CR0_PG		0x80000000	/* enable paging */#define CR0_CD		0x40000000	/* cache disable */#define CR0_NW		0x20000000	/* no write-through */#define CR0_AM		0x00040000	/* alignment check mask */#define CR0_WP		0x00010000	/* write-protect kernel access */#define CR0_NE		0x00000020	/* handle numeric exceptions */#define CR0_ET		0x00000010	/* extension type is 80387 coprocessor */#define CR0_TS		0x00000008	/* task switch */#define CR0_EM		0x00000004	/* emulate coprocessor */#define CR0_MP		0x00000002	/* monitor coprocessor */#define CR0_PE		0x00000001	/* enable protected mode *//* * Page table (PTE) */typedef long *page_table_t;/* * Page directory entry */#define PDE_PRESENT	0x00000001#define PDE_WRITE	0x00000002#define PDE_USER	0x00000004#define PDE_WTHRU	0x00000008#define PDE_NCACHE	0x00000010#define PDE_ACCESS	0x00000020#define PDE_SIZE	0x00000080#define PDE_AVAIL	0x00000e00#define PDE_ADDRESS	0xfffff000/* * Page table entry */#define PTE_PRESENT	0x00000001#define PTE_WRITE	0x00000002#define PTE_USER	0x00000004#define PTE_WTHRU	0x00000008#define PTE_NCACHE	0x00000010#define PTE_ACCESS	0x00000020#define PTE_DIRTY	0x00000040#define PTE_AVAIL	0x00000e00#define PTE_ADDRESS	0xfffff000/* *  Virtual and physical address translation */#define PAGE_DIR(virt)      ((((u_long)(virt)) >> 22) & 0x3ff)#define PAGE_TABLE(virt)    ((((u_long)(virt)) >> 12) & 0x3ff)#define pte_present(pgd, virt)  (pgd[PAGE_DIR(virt)] & PDE_PRESENT)#define page_present(pte, virt) (pte[PAGE_TABLE(virt)] & PTE_PRESENT)#define pgd_to_pte(pgd, virt) \            (page_table_t)phys_to_virt((pgd)[PAGE_DIR(virt)] & PDE_ADDRESS)#define pte_to_page(pte, virt) \            ((pte)[PAGE_TABLE(virt)] & PTE_ADDRESS)/* * Inline CPU functions */static inline void ltr(u_int sel){	__asm__ __volatile__(		"ltr %%ax\n\t"		"jmp 1f\n\t"		"1:\n\t"		:		:"a" (sel));}static inline void lgdt(void *gdt_ptr){	__asm__ __volatile__(		"lgdt (%%eax)\n\t"		"jmp 1f\n\t"		"1:\n\t"		:		:"a" (gdt_ptr));}static inline void lidt(void *idt_ptr){	__asm__ __volatile__(		"lidt (%%eax)\n\t"		"jmp 1f\n\t"		"1:\n\t"		:		:"a" (idt_ptr));}static inline void set_cs(u_short sel){	__asm__ __volatile__(		"movzx %%ax, %%eax\n\t"		"pushl %%eax\n\t"		"pushl $1f\n\t"		"lret\n\t"		"1:\n\t"		:		:"a" (sel));}static inline void set_ds(u_short sel){	__asm__ __volatile__(		"movw %0, %%ds\n\t"		"movw %0, %%es\n\t"		"movw %0, %%fs\n\t"		"movw %0, %%gs\n\t"		"movw %0, %%ss\n\t"		:		:"r" (sel));}static inline void set_esp(u_long val){	__asm__ __volatile__(		"movl %0, %%esp"		:		:"r" (val));}static inline u_long get_esp(void){	register u_long esp;	__asm__ __volatile__(		"movl %%esp, %0"		:"=r" (esp));	return esp;}static inline u_long get_eflags(void){	register u_long eflags;	__asm__ __volatile__(		"pushfl\n\t"		"popl %0\n\t"		:"=r" (eflags));	return eflags;}static inline void set_eflags(u_long val){	__asm__ __volatile__(		"pushl %0\n\t"		"popfl\n\t"		:		:"r" (val));}static inline u_long get_cr0(void){	register u_long _cr0;	__asm__ __volatile__(		"movl %%cr0, %0"		:"=r" (_cr0)		:);	return _cr0;}static inline void set_cr0(u_long _cr0){	__asm__ __volatile__(		"movl %0, %%cr0"		:		:"r" (_cr0));}static inline u_long get_cr2(void){	register u_long _cr2;	__asm__ __volatile__(		"movl %%cr2, %0"		:"=r" (_cr2)		:);	return _cr2;}static inline u_long get_cr3(void){	register u_long _cr3;	__asm__ __volatile__(		"movl %%cr3, %0"		:"=r" (_cr3)		:);	return _cr3;}static inline void set_cr3(u_long _cr3){	__asm__ __volatile__(		"movl %0, %%cr3"		:		:"r" (_cr3));}/* * Enable/disable CPU interrupt */#define sti() __asm__ ("sti"::)#define cli() __asm__ ("cli"::)/* * Flush translation lookaside buffer for * specified page */static inline void flush_tlb_page(void *pg){	__asm__ __volatile__(		"invlpg (%0)"		:		: "r" (pg)		: "memory");}/* * Flush translation lookaside buffer */static inline void flush_tlb(void){	__asm__ __volatile__(		"movl %%cr3, %%eax\n\t"		"movl %%eax, %%cr3\n\t"		:		:		: "ax");}/* * Check if CPU supports "invlpg" (TLB flush per page) function. * Return true if supported. * * TODO: I can not test this because I do not have 386 system. :-( */static inline int check_invlpg(void){	int _i486 = 0;	__asm__ __volatile__(		"pushfl\n\t"		"popl %%eax\n\t"		"movl %%eax, %%ecx\n\t"		"xorl $0x240000, %%eax\n\t"		"pushl %%eax\n\t"		"popfl\n\t"		"pushfl\n\t"		"popl %%eax\n\t"		"xorl %%ecx, %%eax\n\t"		"pushl %%ecx\n\t"		"popfl\n\t"		"testl $0x40000, %%eax\n\t"		"je 1f\n\t"		"movl $1, %0\n\t"		"1:\n\t"		: "=r" (_i486)		:);	return _i486;}/* * I/O instructions */static inline void outb(unsigned char value, int port){	__asm__ __volatile__(		"outb %b0, %w1"		::"a" (value),"Nd" (port));}static inline unsigned char inb(int port){	unsigned char _val;	__asm__ __volatile__(		"inb %w1, %b0"		:"=a" (_val)		:"Nd" (port));	return _val;}static inline void outb_p(unsigned char value, int port){	__asm__ __volatile__(		"outb %b0, %w1\n\t"		"outb %%al, $0x80\n\t"		::"a" (value),"Nd" (port));}static inline unsigned char inb_p(int port){	unsigned char _val;	__asm__ __volatile__(		"inb %w1, %b0\n\t"		"outb %%al, $0x80\n\t"		:"=a" (_val)		:"Nd" (port));	return _val;}extern void tss_set(u_long kstack);extern u_long tss_get(void);extern void trap_set(int vector, void *handler);#endif /* !__ASSEMBLY__ */#endif /* !_CPU_H */

⌨️ 快捷键说明

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