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

📄 l.s

📁 著名操作系统Plan 9的第三版的部分核心源代码。现在很难找到了。Plan 9是bell实验室开发的Unix后继者。
💻 S
📖 第 1 页 / 共 2 页
字号:
#include "mem.h"#define PADDR(a)	((a) & ~KZERO)#define KADDR(a)	(KZERO|(a))/* * Some machine instructions not handled by 8[al]. */#define OP16		BYTE $0x66#define	DELAY		BYTE $0xEB; BYTE $0x00	/* JMP .+2 */#define CPUID		BYTE $0x0F; BYTE $0xA2	/* CPUID, argument in AX */#define WRMSR		BYTE $0x0F; BYTE $0x30	/* WRMSR, argument in AX/DX (lo/hi) */#define RDMSR		BYTE $0x0F; BYTE $0x32	/* RDMSR, result in AX/DX (lo/hi) */#define WBINVD		BYTE $0x0F; BYTE $0x09/* * Macros for calculating offsets within the page directory base * and page tables. Note that these are assembler-specific hence * the '<<2'. */#define PDO(a)		(((((a))>>22) & 0x03FF)<<2)#define PTO(a)		(((((a))>>12) & 0x03FF)<<2)/* * Entered here from the bootstrap programme possibly via a jump to 0x00100020, so * need to make another jump to set the correct virtual address. * In protected mode with paging turned on, the first 4MB of physical memory mapped * to KZERO and up. */TEXT _start0x00100020(SB),$0	CLI	MOVL	$_start0x80100020(SB), AX	JMP*	AX/* * First check if the bootstrap programme left the first 4MB nicely mapped, otherwise * make the basic page tables for processor 0. Four pages are needed for the basic set: * a page directory, a page table for mapping the first 4MB of physical memory, and * virtual and physical pages for mapping the Mach structure. * The remaining PTEs will be allocated later when memory is sized. */TEXT _start0x80100020(SB), $0	MOVL	CR3, AX				/* check the page directory base */	CMPL	AX, $PADDR(CPU0PDB)	JEQ	_clearbss	MOVL	$CPU0PDB, DI			/* clear 4 pages for the tables etc. */	XORL	AX, AX	MOVL	$(4*BY2PG), CX	SHRL	$2, CX	CLD	REP;	STOSL	MOVL	$CPU0PDB, AX	ADDL	$PDO(KZERO), AX			/* page directory offset for KZERO */	MOVL	$PADDR(CPU0PTE), (AX)		/* PTE's for 0x80000000 */	MOVL	$(PTEWRITE|PTEVALID), BX	/* page permissions */	ORL	BX, (AX)	MOVL	$CPU0PTE, AX			/* first page of page table */	MOVL	$1024, CX			/* 1024 pages in 4MB */_setpte:	MOVL	BX, (AX)	ADDL	$(1<<PGSHIFT), BX	ADDL	$4, AX	LOOP	_setpte	MOVL	$CPU0PTE, AX	ADDL	$PTO(MACHADDR), AX		/* page table entry offset for MACHADDR */	MOVL	$PADDR(CPU0MACH), (AX)		/* PTE for Mach */	MOVL	$(PTEWRITE|PTEVALID), BX	/* page permissions */	ORL	BX, (AX)/* * Now ready to use the new map. Make sure the processor options are what is wanted. * It is necessary on some processors to follow mode switching with a JMP instruction * to clear the prefetch queues. * There's a little mystery here - the Pentium Pro appears to need an identity * mmu map for the switch to virtual mode. The manual doesn't say this is necessary * and it isn't required on the Pentium. * To this end double map KZERO at virtual 0 and undo the mapping once virtual * nirvana has been attained. */	MOVL	$PADDR(CPU0PDB), CX		/* load address of page directory */	MOVL	CX, BX	MOVL	(PDO(KZERO))(BX), DX		/* double-map KZERO at 0 */	MOVL	DX, (PDO(0))(BX)	MOVL	CX, CR3	DELAY					/* JMP .+2 */	MOVL	CR0, DX	ORL	$0x80010000, DX			/* PG|WP */	ANDL	$~0x6000000A, DX		/* ~(CD|NW|TS|MP) */	MOVL	$_startpg(SB), AX	MOVL	DX, CR0				/* turn on paging */	JMP*	AX/* * Basic machine environment set, can clear BSS and create a stack. * The stack starts at the top of the page containing the Mach structure. * The x86 architecture forces the use of the same virtual address for * each processor's Mach structure, so the global Mach pointer 'm' can * be initialised here. */TEXT _startpg(SB), $0	MOVL	CX, AX				/* physical address of PDB */	ORL	$KZERO, AX	MOVL	$0, (PDO(0))(AX)		/* undo double-map of KZERO at 0 */	MOVL	CX, CR3				/* load and flush the mmu */_clearbss:	MOVL	$edata(SB), DI	XORL	AX, AX	MOVL	$end(SB), CX	SUBL	DI, CX				/* end-edata bytes */	SHRL	$2, CX				/* end-edata doublewords */	CLD	REP;	STOSL				/* clear BSS */	MOVL	$MACHADDR, SP	MOVL	SP, m(SB)			/* initialise global Mach pointer */	MOVL	$0, 0(SP)			/* initialise m->machno */	ADDL	$(MACHSIZE-4), SP		/* initialise stack *//* * Need to do one final thing to ensure a clean machine environment, * clear the EFLAGS register, which can only be done once there is a stack. */	MOVL	$0, AX	PUSHL	AX	POPFL	CALL	main(SB)/* * Park a processor. Should never fall through a return from main to here, * should only be called by application processors when shutting down. */TEXT idle(SB), $0_idle:	STI	HLT	JMP	_idle/* * Port I/O. *	in[bsl]		input a byte|short|long *	ins[bsl]	input a string of bytes|shorts|longs *	out[bsl]	output a byte|short|long *	outs[bsl]	output a string of bytes|shorts|longs */TEXT inb(SB), $0	MOVL	port+0(FP), DX	XORL	AX, AX	INB	RETTEXT insb(SB), $0	MOVL	port+0(FP), DX	MOVL	address+4(FP), DI	MOVL	count+8(FP), CX	CLD	REP;	INSB	RETTEXT ins(SB), $0	MOVL	port+0(FP), DX	XORL	AX, AX	OP16;	INL	RETTEXT inss(SB), $0	MOVL	port+0(FP), DX	MOVL	address+4(FP), DI	MOVL	count+8(FP), CX	CLD	REP;	OP16; INSL	RETTEXT inl(SB), $0	MOVL	port+0(FP), DX	INL	RETTEXT insl(SB), $0	MOVL	port+0(FP), DX	MOVL	address+4(FP), DI	MOVL	count+8(FP), CX	CLD	REP;	INSL	RETTEXT outb(SB), $0	MOVL	port+0(FP), DX	MOVL	byte+4(FP), AX	OUTB	RETTEXT outsb(SB),$0	MOVL	port+0(FP), DX	MOVL	address+4(FP), SI	MOVL	count+8(FP), CX	CLD	REP;	OUTSB	RETTEXT outs(SB), $0	MOVL	port+0(FP), DX	MOVL	short+4(FP), AX	OP16;	OUTL	RETTEXT outss(SB), $0	MOVL	port+0(FP), DX	MOVL	address+4(FP), SI	MOVL	count+8(FP), CX	CLD	REP;	OP16; OUTSL	RETTEXT outl(SB), $0	MOVL	port+0(FP), DX	MOVL	long+4(FP), AX	OUTL	RETTEXT outsl(SB), $0	MOVL	port+0(FP), DX	MOVL	address+4(FP), SI	MOVL	count+8(FP), CX	CLD	REP;	OUTSL	RET/* * Read/write various system registers. * CR4 and the 'model specific registers' should only be read/written * after it has been determined the processor supports them */TEXT lgdt(SB), $0				/* GDTR - global descriptor table */	MOVL	gdtptr+0(FP), AX	MOVL	(AX), GDTR	RETTEXT lidt(SB), $0				/* IDTR - interrupt descriptor table */	MOVL	idtptr+0(FP), AX	MOVL	(AX), IDTR	RETTEXT ltr(SB), $0				/* TR - task register */	MOVL	tptr+0(FP), AX	MOVW	AX, TASK	RETTEXT getcr0(SB), $0				/* CR0 - processor control */	MOVL	CR0, AX	RETTEXT getcr2(SB), $0				/* CR2 - page fault linear address */	MOVL	CR2, AX	RETTEXT getcr3(SB), $0				/* CR3 - page directory base */	MOVL	CR3, AX	RETTEXT putcr3(SB), $0	MOVL	cr3+0(FP), AX	MOVL	AX, CR3	RETTEXT getcr4(SB), $0				/* CR4 - extensions */	MOVL	CR4, AX	RETTEXT putcr4(SB), $0	MOVL	cr4+0(FP), AX	MOVL	AX, CR4	RETTEXT rdmsr(SB), $0				/* model-specific register */	MOVL	index+0(FP), CX	RDMSR	MOVL	vlong+4(FP), CX			/* &vlong */	MOVL	AX, (CX)			/* lo */	MOVL	DX, 4(CX)			/* hi */	RET	TEXT wrmsr(SB), $0	MOVL	index+0(FP), CX	MOVL	lo+4(FP), AX	MOVL	hi+8(FP), DX	WRMSR	RETTEXT wbinvd(SB), $0	WBINVD	RET/* * Try to determine the CPU type which requires fiddling with EFLAGS. * If the Id bit can be toggled then the CPUID instruciton can be used * to determine CPU identity and features. First have to check if it's * a 386 (Ac bit can't be set). If it's not a 386 and the Id bit can't be * toggled then it's an older 486 of some kind. * *	cpuid(id[], &ax, &dx); */TEXT cpuid(SB), $0	MOVL	$0x240000, AX	PUSHL	AX	POPFL					/* set Id|Ac */	PUSHFL	POPL	BX				/* retrieve value */	MOVL	$0, AX	PUSHL	AX	POPFL					/* clear Id|Ac, EFLAGS initialised */	PUSHFL	POPL	AX				/* retrieve value */	XORL	BX, AX	TESTL	$0x040000, AX			/* Ac */	JZ	_cpu386				/* can't set this bit on 386 */	TESTL	$0x200000, AX			/* Id */	JZ	_cpu486				/* can't toggle this bit on some 486 */	MOVL	$0, AX	CPUID	MOVL	id+0(FP), BP	MOVL	BX, 0(BP)			/* "Genu" "Auth" "Cyri" */	MOVL	DX, 4(BP)			/* "ineI" "enti" "xIns" */	MOVL	CX, 8(BP)			/* "ntel" "cAMD" "tead" */	MOVL	$1, AX	CPUID	JMP	_cpuid_cpu486:	MOVL	$0x400, AX	MOVL	$0, DX	JMP	_cpuid_cpu386:	MOVL	$0x300, AX	MOVL	$0, DX_cpuid:	MOVL	ax+4(FP), BP	MOVL	AX, 0(BP)	MOVL	dx+8(FP), BP	MOVL	DX, 0(BP)	RET/* * Basic timing loop to determine CPU frequency. */TEXT aamloop(SB), $0	MOVL	count+0(FP), CX_aamloop:	AAM	LOOP	_aamloop	RET/* * Floating point. */#define	FPOFF								;\	WAIT								;\	MOVL	CR0, AX							;\	ANDL	$~0x4, AX			/* EM=0 */		;\	ORL	$0x28, AX			/* NE=1, TS=1 */	;\	MOVL	AX, CR0#define	FPON								;\	MOVL	CR0, AX							;\	ANDL	$~0xC, AX			/* EM=0, TS=0 */	;\	MOVL	AX, CR0	TEXT fpoff(SB), $0				/* disable */	FPOFF	RETTEXT fpinit(SB), $0				/* enable and init */	FPON	FINIT	WAIT	PUSHW	$0x033E	FLDCW	0(SP)				/* ignore underflow/precision, signal others */	POPW	AX	WAIT	RETTEXT fpsave(SB), $0				/* save state and disable */	MOVL	p+0(FP), AX	FSAVE	0(AX)				/* no WAIT */	FPOFF	RET

⌨️ 快捷键说明

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