xref: /plan9/sys/src/9/pc/apbootstrap.s (revision 4de34a7edde43207e841ec91ecd12e6cf5f5ebe7)
1*4de34a7eSDavid du Colombier/*
2*4de34a7eSDavid du Colombier * Start an Application Processor. This must be placed on a 4KB boundary
3*4de34a7eSDavid du Colombier * somewhere in the 1st MB of conventional memory (APBOOTSTRAP). However,
4*4de34a7eSDavid du Colombier * due to some shortcuts below it's restricted further to within the 1st
5*4de34a7eSDavid du Colombier * 64KB. The AP starts in real-mode, with
6*4de34a7eSDavid du Colombier *   CS selector set to the startup memory address/16;
7*4de34a7eSDavid du Colombier *   CS base set to startup memory address;
8*4de34a7eSDavid du Colombier *   CS limit set to 64KB;
9*4de34a7eSDavid du Colombier *   CPL and IP set to 0.
10*4de34a7eSDavid du Colombier */
117dd7cddfSDavid du Colombier#include "mem.h"
127dd7cddfSDavid du Colombier
137dd7cddfSDavid du Colombier#define NOP		BYTE $0x90		/* NOP */
147dd7cddfSDavid du Colombier#define LGDT(gdtptr)	BYTE $0x0F;		/* LGDT */			\
157dd7cddfSDavid du Colombier			BYTE $0x01; BYTE $0x16;					\
167dd7cddfSDavid du Colombier			WORD $gdtptr
177dd7cddfSDavid du Colombier#define FARJUMP16(s, o)	BYTE $0xEA;		/* far jump to ptr16:16 */	\
187dd7cddfSDavid du Colombier			WORD $o; WORD $s;					\
197dd7cddfSDavid du Colombier			NOP; NOP; NOP
207dd7cddfSDavid du Colombier#define FARJUMP32(s, o)	BYTE $0x66;		/* far jump to ptr32:16 */	\
217dd7cddfSDavid du Colombier			BYTE $0xEA; LONG $o; WORD $s
227dd7cddfSDavid du Colombier
237dd7cddfSDavid du Colombier#define	DELAY		BYTE $0xEB;		/* JMP .+2 */			\
247dd7cddfSDavid du Colombier			BYTE $0x00
257dd7cddfSDavid du Colombier#define INVD		BYTE $0x0F; BYTE $0x08
267dd7cddfSDavid du Colombier#define WBINVD		BYTE $0x0F; BYTE $0x09
277dd7cddfSDavid du Colombier
287dd7cddfSDavid du Colombier/*
297dd7cddfSDavid du Colombier * Macros for calculating offsets within the page directory base
307dd7cddfSDavid du Colombier * and page tables. Note that these are assembler-specific hence
317dd7cddfSDavid du Colombier * the '<<2'.
327dd7cddfSDavid du Colombier */
337dd7cddfSDavid du Colombier#define PDO(a)		(((((a))>>22) & 0x03FF)<<2)
347dd7cddfSDavid du Colombier#define PTO(a)		(((((a))>>12) & 0x03FF)<<2)
357dd7cddfSDavid du Colombier
367dd7cddfSDavid du ColombierTEXT apbootstrap(SB), $0
377dd7cddfSDavid du Colombier	FARJUMP16(0, _apbootstrap(SB))
387dd7cddfSDavid du ColombierTEXT _apvector(SB), $0				/* address APBOOTSTRAP+0x08 */
397dd7cddfSDavid du Colombier	LONG $0
407dd7cddfSDavid du ColombierTEXT _appdb(SB), $0				/* address APBOOTSTRAP+0x0C */
417dd7cddfSDavid du Colombier	LONG $0
427dd7cddfSDavid du ColombierTEXT _apapic(SB), $0				/* address APBOOTSTRAP+0x10 */
437dd7cddfSDavid du Colombier	LONG $0
447dd7cddfSDavid du ColombierTEXT _apbootstrap(SB), $0			/* address APBOOTSTRAP+0x14 */
457dd7cddfSDavid du Colombier	MOVW	CS, AX
467dd7cddfSDavid du Colombier	MOVW	AX, DS				/* initialise DS */
477dd7cddfSDavid du Colombier
487dd7cddfSDavid du Colombier	LGDT(gdtptr(SB))			/* load a basic gdt */
497dd7cddfSDavid du Colombier
507dd7cddfSDavid du Colombier	MOVL	CR0, AX
517dd7cddfSDavid du Colombier	ORL	$1, AX
527dd7cddfSDavid du Colombier	MOVL	AX, CR0				/* turn on protected mode */
537dd7cddfSDavid du Colombier	DELAY					/* JMP .+2 */
547dd7cddfSDavid du Colombier
557dd7cddfSDavid du Colombier	BYTE $0xB8; WORD $SELECTOR(1, SELGDT, 0)/* MOVW $SELECTOR(1, SELGDT, 0), AX */
567dd7cddfSDavid du Colombier	MOVW	AX, DS
577dd7cddfSDavid du Colombier	MOVW	AX, ES
587dd7cddfSDavid du Colombier	MOVW	AX, FS
597dd7cddfSDavid du Colombier	MOVW	AX, GS
607dd7cddfSDavid du Colombier	MOVW	AX, SS
617dd7cddfSDavid du Colombier
627dd7cddfSDavid du Colombier	FARJUMP32(SELECTOR(2, SELGDT, 0), _ap32-KZERO(SB))
637dd7cddfSDavid du Colombier
647dd7cddfSDavid du Colombier/*
659a747e4fSDavid du Colombier * For Pentiums and higher, the code that enables paging must come from
669a747e4fSDavid du Colombier * pages that are identity mapped.
677dd7cddfSDavid du Colombier * To this end double map KZERO at virtual 0 and undo the mapping once virtual
687dd7cddfSDavid du Colombier * nirvana has been obtained.
697dd7cddfSDavid du Colombier */
707dd7cddfSDavid du ColombierTEXT _ap32(SB), $0
717dd7cddfSDavid du Colombier	MOVL	_appdb-KZERO(SB), CX		/* physical address of PDB */
727dd7cddfSDavid du Colombier	MOVL	(PDO(KZERO))(CX), DX		/* double-map KZERO at 0 */
737dd7cddfSDavid du Colombier	MOVL	DX, (PDO(0))(CX)
747dd7cddfSDavid du Colombier	MOVL	CX, CR3				/* load and flush the mmu */
757dd7cddfSDavid du Colombier
767dd7cddfSDavid du Colombier	MOVL	CR0, DX
777dd7cddfSDavid du Colombier	ORL	$0x80010000, DX			/* PG|WP */
787dd7cddfSDavid du Colombier	ANDL	$~0x6000000A, DX		/* ~(CD|NW|TS|MP) */
797dd7cddfSDavid du Colombier
807dd7cddfSDavid du Colombier	MOVL	$_appg(SB), AX
817dd7cddfSDavid du Colombier	MOVL	DX, CR0				/* turn on paging */
827dd7cddfSDavid du Colombier	JMP*	AX
837dd7cddfSDavid du Colombier
847dd7cddfSDavid du ColombierTEXT _appg(SB), $0
857dd7cddfSDavid du Colombier	MOVL	CX, AX				/* physical address of PDB */
867dd7cddfSDavid du Colombier	ORL	$KZERO, AX
877dd7cddfSDavid du Colombier	MOVL	$0, (PDO(0))(AX)		/* undo double-map of KZERO at 0 */
887dd7cddfSDavid du Colombier	MOVL	CX, CR3				/* load and flush the mmu */
897dd7cddfSDavid du Colombier
907dd7cddfSDavid du Colombier	MOVL	$(MACHADDR+MACHSIZE-4), SP
917dd7cddfSDavid du Colombier
927dd7cddfSDavid du Colombier	MOVL	$0, AX
937dd7cddfSDavid du Colombier	PUSHL	AX
947dd7cddfSDavid du Colombier	POPFL
957dd7cddfSDavid du Colombier
967dd7cddfSDavid du Colombier	MOVL	_apapic(SB), AX
977dd7cddfSDavid du Colombier	MOVL	AX, (SP)
987dd7cddfSDavid du Colombier	MOVL	_apvector(SB), AX
997dd7cddfSDavid du Colombier	CALL*	AX
1007dd7cddfSDavid du Colombier_aphalt:
1017dd7cddfSDavid du Colombier	HLT
1027dd7cddfSDavid du Colombier	JMP	_aphalt
1037dd7cddfSDavid du Colombier
1047dd7cddfSDavid du ColombierTEXT gdt(SB), $0
1057dd7cddfSDavid du Colombier	LONG $0x0000; LONG $0
1067dd7cddfSDavid du Colombier	LONG $0xFFFF; LONG $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
1077dd7cddfSDavid du Colombier	LONG $0xFFFF; LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
1087dd7cddfSDavid du ColombierTEXT gdtptr(SB), $0
1099a747e4fSDavid du Colombier	WORD	$(3*8-1)
1107dd7cddfSDavid du Colombier	LONG	$gdt-KZERO(SB)
111