Plan 9 from Bell Labs’s /usr/web/sources/contrib/uriel/changes/2005/1101/4

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


Load kernels at non-standard base addresses.  Also real-mode assembly.
 [rsc] --rw-rw-r-- M 140560 glenda sys 8421 Nov  1 18:20 sys/src/boot/pc/boot.c
	/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/boot.c:149,155 - 
	/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/boot.c:149,155
	  		if(php->type != LOAD)
	  			continue;
	  		offset = php->offset;
	- 		paddr = (char*)(php->paddr & ~0xF0000000);
	+ 		paddr = (char*)PADDR(php->paddr);
	  		if(offset < curoff){
	  			/*
	  			 * Can't (be bothered to) rewind the
	/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/boot.c:215,221 - 
	/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/boot.c:215,221
	  	if(php->filesz < php->memsz){
	  		print("%lud",  php->memsz-php->filesz);
	  		elftotal += php->memsz-php->filesz;
	- 		memset((char*)((php->paddr & ~0xF0000000)+php->filesz), 0, php->memsz-php->filesz);
	+ 		memset((char*)(PADDR(php->paddr)+php->filesz), 0, php->memsz-php->filesz);
	  	}
	  	curoff = php->offset+php->filesz;
	  	curphdr++;
	/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/boot.c:326,332 - 
	/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/boot.c:326,332
	  		case READ9TEXT:
	  			ep = &b->exec;
	  			b->state = READ9DATA;
	- 			b->bp = (char*)PGROUND(GLLONG(ep->entry)+GLLONG(ep->text));
	+ 			b->bp = (char*)PGROUND(PADDR(GLLONG(ep->entry))+GLLONG(ep->text));
	  			b->wp = b->bp;
	  			b->ep = b->wp + GLLONG(ep->data);
	  			print("+%ld", GLLONG(ep->data));
	/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/boot.c:432,438 - 
	/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/boot.c:432,438
	  		}
	  
	  		/* relocate data to start at page boundary */
	- 		memmove((void*)PGROUND(entry+text), (void*)(entry+text), data);
	+ 		memmove((void*)PGROUND(PADDR(entry+text)), (void*)(PADDR(entry+text)), data);
	  
	  		print("entry: %lux\n", entry);
	  		warp9(PADDR(entry));
 [rsc] --rw-rw-r-- M 140560 glenda sys 4273 Nov  1 18:20 sys/src/boot/pc/fns.h
	/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/fns.h:106,111 - 
	/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/fns.h:106,113
	  int	spllo(void);
	  void	splx(int);
	  void	trapinit(void);
	+ void	trapdisable(void);
	+ void	trapenable(void);
	  void	uartdrain(void);
	  void	uartspecial(int, void (*)(int), int (*)(void), int);
	  void	uartputs(IOQ*, char*, int);
	/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/fns.h:130,136 - 
	/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/fns.h:132,138
	  #define	PLLONG(p,v)	(p)[3]=(v);(p)[2]=(v)>>8;(p)[1]=(v)>>16;(p)[0]=(v)>>24
	  
	  #define KADDR(a)	((void*)((ulong)(a)|KZERO))
	- #define PADDR(a)	((ulong)(a)&~KZERO)
	+ #define PADDR(a)	((ulong)(a)&~0xF0000000)
	  
	  #define	HOWMANY(x, y)	(((x)+((y)-1))/(y))
	  #define ROUNDUP(x, y)	(HOWMANY((x), (y))*(y))
 [rsc] --rw-rw-r-- M 140560 glenda sys 18115 Nov  1 18:20 sys/src/boot/pc/l.s
	/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/l.s:356,367 - 
	/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/l.s:356,370
	  	LONG	$(0xFFFF)
	  	LONG	$(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
	  
	+ 	/* exec segment descriptor for 4 gigabytes (PL 0) 16-bit */
	+ 	LONG	$(0xFFFF)
	+ 	LONG	$(SEGG|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
	+ 
	  /*
	   *  pointer to initial gdt
	   */
	  TEXT	tgdtptr(SB),$0
	- 
	- 	WORD	$(3*8)
	+ 	WORD	$(4*8)
	  	LONG	$tgdt-KZERO(SB)
	  
	  /*
	/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/l.s:847,849 - 
	/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/l.s:850,1079
	  #else
	  DATA	pxe+0(SB)/4, $0
	  #endif /* PXE */
	+ 
	+ /*
	+  * Save registers.
	+  */
	+ TEXT saveregs(SB), $0
	+ 	/* appease 8l */
	+ 	SUBL $32, SP
	+ 	POPL AX
	+ 	POPL AX
	+ 	POPL AX
	+ 	POPL AX
	+ 	POPL AX
	+ 	POPL AX
	+ 	POPL AX
	+ 	POPL AX
	+ 	
	+ 	PUSHL	AX
	+ 	PUSHL	BX
	+ 	PUSHL	CX
	+ 	PUSHL	DX
	+ 	PUSHL	BP
	+ 	PUSHL	DI
	+ 	PUSHL	SI
	+ 	PUSHFL
	+ 
	+ 	XCHGL	32(SP), AX	/* swap return PC and saved flags */
	+ 	XCHGL	0(SP), AX
	+ 	XCHGL	32(SP), AX
	+ 	RET
	+ 
	+ TEXT restoreregs(SB), $0
	+ 	/* appease 8l */
	+ 	PUSHL	AX
	+ 	PUSHL	AX
	+ 	PUSHL	AX
	+ 	PUSHL	AX
	+ 	PUSHL	AX
	+ 	PUSHL	AX
	+ 	PUSHL	AX
	+ 	PUSHL	AX
	+ 	ADDL	$32, SP
	+ 	
	+ 	XCHGL	32(SP), AX	/* swap return PC and saved flags */
	+ 	XCHGL	0(SP), AX
	+ 	XCHGL	32(SP), AX
	+ 
	+ 	POPFL
	+ 	POPL	SI
	+ 	POPL	DI
	+ 	POPL	BP
	+ 	POPL	DX
	+ 	POPL	CX
	+ 	POPL	BX
	+ 	POPL	AX
	+ 	RET
	+ 
	+ /*
	+  * Assumed to be in protected mode at time of call.
	+  * Switch to real mode, execute an interrupt, and
	+  * then switch back to protected mode.  
	+  *
	+  * Assumes:
	+  *
	+  *	- no device interrupts are going to come in
	+  *	- 0-16MB is identity mapped in page tables
	+  *	- can use code segment 0x1000 in real mode
	+  *		to get at l.s code
	+  */
	+ TEXT realmodeidtptr(SB), $0
	+ 	WORD	$(4*256-1)
	+ 	LONG	$0
	+ 
	+ TEXT realmode0(SB), $0
	+ 	CALL	saveregs(SB)
	+ 
	+ 	/* switch to low code address */
	+ 	LEAL	physcode-KZERO(SB), AX
	+ 	JMP *AX
	+ 
	+ TEXT physcode(SB), $0
	+ 
	+ 	/* switch to low stack */
	+ 	MOVL	SP, AX
	+ 	MOVL	$0x7C00, SP
	+ 	PUSHL	AX
	+ 
	+ 	/* load IDT with real-mode version; GDT already fine */
	+ 	MOVL	realmodeidtptr(SB), IDTR
	+ 
	+ 	/* edit INT $0x00 instruction below */
	+ 	MOVL	realmodeintr(SB), AX
	+ 	MOVB	AX, realmodeintrinst+1(SB)
	+ 
	+ 	/* disable paging */
	+ 	MOVL	CR0, AX
	+ 	ANDL	$0x7FFFFFFF, AX
	+ 	MOVL	AX, CR0
	+ 	/* JMP .+2 to clear prefetch queue*/
	+ 	BYTE $0xEB; BYTE $0x00
	+ 
	+ 	/* jump to 16-bit code segment */
	+ /*	JMPFAR	SELECTOR(3, SELGDT, 0):$again16bit(SB) /**/
	+ 	 BYTE	$0xEA
	+ 	 LONG	$again16bit-KZERO(SB)
	+ 	 WORD	$SELECTOR(3, SELGDT, 0)
	+ 
	+ TEXT again16bit(SB), $0
	+ 	/*
	+ 	 * Now in 16-bit compatibility mode.
	+ 	 * These are 32-bit instructions being interpreted
	+ 	 * as 16-bit instructions.  I'm being lazy and
	+ 	 * not using the macros because I know when
	+ 	 * the 16- and 32-bit instructions look the same
	+ 	 * or close enough.
	+ 	 */
	+ 
	+ 	/* disable protected mode and jump to real mode cs */
	+ 	OPSIZE; MOVL CR0, AX
	+ 	OPSIZE; XORL BX, BX
	+ 	OPSIZE; INCL BX
	+ 	OPSIZE; XORL BX, AX
	+ 	OPSIZE; MOVL AX, CR0
	+ 
	+ 	/* JMPFAR 0x1000:now16real */
	+ 	 BYTE $0xEA
	+ 	 WORD	$now16real-KZERO(SB)
	+ 	 WORD	$0x1000
	+ 
	+ TEXT now16real(SB), $0
	+ 	/* copy the registers for the bios call */
	+ 	LWI(0x1000, rAX)
	+ 	MOVW	AX,SS
	+ 	LWI(realmoderegs(SB), rBP)
	+ 	
	+ 	/* offsets are in Ureg */
	+ 	LXW(44, xBP, rAX)
	+ 	MOVW	AX, DS
	+ 	LXW(40, xBP, rAX)
	+ 	MOVW	AX, ES
	+ 
	+ 	OPSIZE; LXW(0, xBP, rDI)
	+ 	OPSIZE; LXW(4, xBP, rSI)
	+ 	OPSIZE; LXW(16, xBP, rBX)
	+ 	OPSIZE; LXW(20, xBP, rDX)
	+ 	OPSIZE; LXW(24, xBP, rCX)
	+ 	OPSIZE; LXW(28, xBP, rAX)
	+ 
	+ 	CLC
	+ 
	+ TEXT realmodeintrinst(SB), $0
	+ 	INT $0x00
	+ 
	+ 	/* save the registers after the call */
	+ 
	+ 	LWI(0x7bfc, rSP)
	+ 	OPSIZE; PUSHFL
	+ 	OPSIZE; PUSHL AX
	+ 
	+ 	LWI(0x1000, rAX)
	+ 	MOVW	AX,SS
	+ 	LWI(realmoderegs(SB), rBP)
	+ 	
	+ 	OPSIZE; SXW(rDI, 0, xBP)
	+ 	OPSIZE; SXW(rSI, 4, xBP)
	+ 	OPSIZE; SXW(rBX, 16, xBP)
	+ 	OPSIZE; SXW(rDX, 20, xBP)
	+ 	OPSIZE; SXW(rCX, 24, xBP)
	+ 	OPSIZE; POPL AX
	+ 	OPSIZE; SXW(rAX, 28, xBP)
	+ 
	+ 	MOVW	DS, AX
	+ 	OPSIZE; SXW(rAX, 44, xBP)
	+ 	MOVW	ES, AX
	+ 	OPSIZE; SXW(rAX, 40, xBP)
	+ 
	+ 	OPSIZE; POPL AX
	+ 	OPSIZE; SXW(rAX, 64, xBP)	/* flags */
	+ 
	+ 	/* re-enter protected mode and jump to 32-bit code */
	+ 	OPSIZE; MOVL $1, AX
	+ 	OPSIZE; MOVL AX, CR0
	+ 	
	+ /*	JMPFAR	SELECTOR(2, SELGDT, 0):$again32bit(SB) /**/
	+ 	 OPSIZE
	+ 	 BYTE $0xEA
	+ 	 LONG	$again32bit-KZERO(SB)
	+ 	 WORD	$SELECTOR(2, SELGDT, 0)
	+ 
	+ TEXT again32bit(SB), $0
	+ 	MOVW	$SELECTOR(1, SELGDT, 0),AX
	+ 	MOVW	AX,DS
	+ 	MOVW	AX,SS
	+ 	MOVW	AX,ES
	+ 	MOVW	AX,FS
	+ 	MOVW	AX,GS
	+ 
	+ 	/* enable paging and jump to kzero-address code */
	+ 	MOVL	CR0, AX
	+ 	ORL	$0x80000000, AX
	+ 	MOVL	AX, CR0
	+ 	LEAL	again32kzero(SB), AX
	+ 	JMP*	AX
	+ 
	+ TEXT again32kzero(SB), $0
	+ 	/* breathe a sigh of relief - back in 32-bit protected mode */
	+ 
	+ 	/* switch to old stack */	
	+ 	PUSHL	AX	/* match popl below for 8l */
	+ 	MOVL	$0x7BFC, SP
	+ 	POPL	SP
	+ 
	+ 	/* restore idt */
	+ 	MOVL	idtptr(SB),IDTR
	+ 
	+ 	CALL	restoreregs(SB)
	+ 	RET
	+ 
	+ TEXT realmoderegs(SB), $0
	+ 	LONG $0; LONG $0; LONG $0; LONG $0
	+ 	LONG $0; LONG $0; LONG $0; LONG $0
	+ 	LONG $0; LONG $0; LONG $0; LONG $0
	+ 	LONG $0; LONG $0; LONG $0; LONG $0
	+ 	LONG $0; LONG $0; LONG $0; LONG $0
	+ 
	+ TEXT realmodeintr(SB), $0
	+ 	LONG $0
	+ 
 [rsc] --rw-rw-r-- M 140560 glenda sys 8932 Nov  1 18:20 sys/src/boot/pc/load.c
	/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/load.c:548,553 - 
	/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/load.c:548,557
	  		sddetach();
	  
	  	consdrain();
	+ 	
	+ 	splhi();
	+ 	trapdisable();
	+ 
	  	/*
	  	 * This is where to push things on the stack to
	  	 * boot *BSD systems, e.g.
 [rsc] --rw-rw-r-- M 140560 glenda sys 3371 Nov  1 18:20 sys/src/boot/pc/mem.h
	/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/mem.h:6,17 - 
	/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/mem.h:6,17
	   * Sizes
	   */
	  #define	BI2BY		8			/* bits per byte */
	- #define BI2WD		32			/* bits per word */
	+ #define	BI2WD		32			/* bits per word */
	  #define	BY2WD		4			/* bytes per word */
	  #define	BY2PG		4096			/* bytes per page */
	  #define	WD2PG		(BY2PG/BY2WD)		/* words per page */
	  #define	PGSHIFT		12			/* log(BY2PG) */
	- #define PGROUND(s)	(((s)+(BY2PG-1))&~(BY2PG-1))
	+ #define	PGROUND(s)	(((s)+(BY2PG-1))&~(BY2PG-1))
	  
	  #define	MAXMACH		1			/* max # cpus system can run */
	  
	/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/mem.h:102,112 - 
	/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/mem.h:102,112
	   */
	  #define	PTEVALID	(1<<0)
	  #define	PTEUNCACHED	0		/* everything is uncached */
	- #define PTEWRITE	(1<<1)
	+ #define	PTEWRITE	(1<<1)
	  #define	PTERONLY	(0<<1)
	  #define	PTEKERNEL	(0<<2)
	  #define	PTEUSER		(1<<2)
	- #define PTESIZE		(1<<7)
	+ #define	PTESIZE		(1<<7)
	  
	  /*
	   *  flag register bits that we care about
 [rsc] --rw-rw-r-- M 140560 glenda sys 7501 Nov  1 18:20 sys/src/boot/pc/trap.c
	/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/trap.c:99,104 - 
	/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/trap.c:99,119
	  	}
	  }
	  
	+ void
	+ trapdisable(void)
	+ {
	+ 	outb(Int0aux, 0xFF);
	+ 	outb(Int1aux, 0xFF);
	+ }
	+ 
	+ void
	+ trapenable(void)
	+ {
	+ 	outb(Int0aux, int0mask);
	+ 	outb(Int1aux, int1mask);
	+ }
	+ 
	+ 
	  /*
	   *  set up the interrupt/trap gates
	   */
	/n/sourcesdump/2005/1101/plan9/sys/src/boot/pc/trap.c:298,301 - 
	/n/sourcesdump/2005/1102/plan9/sys/src/boot/pc/trap.c:313,331
	  		(*h->r)(ur, h->arg);
	  		h = h->next;
	  	} while(h);
	+ }
	+ 
	+ void
	+ realmode(int intr, Ureg *ureg)
	+ {
	+ 	extern void realmode0(void);	/* in l.s */
	+ 	extern int realmodeintr;
	+ 	extern Ureg realmoderegs;
	+ 
	+ 	realmoderegs = *ureg;
	+ 	realmodeintr = intr;
	+ 	trapdisable();
	+ 	realmode0();
	+ 	trapenable();
	+ 	*ureg = realmoderegs;
	  }


Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].