mtd/docboot doc_bootstub.S,1.6,1.7

dbrown at infradead.org dbrown at infradead.org
Thu Apr 21 11:25:06 EDT 2005


Update of /home/cvs/mtd/docboot
In directory phoenix.infradead.org:/tmp/cvs-serv21629

Modified Files:
	doc_bootstub.S 
Log Message:
Detect more than 16M of high memory.  Also add some cleanups and error checking.


Index: doc_bootstub.S
===================================================================
RCS file: /home/cvs/mtd/docboot/doc_bootstub.S,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- doc_bootstub.S	5 Apr 2005 19:36:21 -0000	1.6
+++ doc_bootstub.S	21 Apr 2005 15:25:03 -0000	1.7
@@ -69,7 +69,9 @@
    2) Copy the rest of the kernel (the protected-mode part) from the DOC into
       high memory starting at 0x100000.  BIOS int15h function 87h is used to
       perform the low-to-high copy.
-   3) Patch some variables in the real-mode kernel, that a Linux bootloader is
+   3) Copy the initrd (if there is one) to the top of high memory using
+      int15/87h.
+   4) Patch some variables in the real-mode kernel, that a Linux bootloader is
       supposed to set.  Then jump to the real-mode kernel.
  */
 
@@ -80,10 +82,10 @@
 
 	cld
 
-	movw	setup_seg, %es
+	pushw	%cs
+
 	movw	doc_seg, %ds
 	movw	$BXREG, %bx
-	movw	$SIREG, %si
 
 		/* Enable the DiskOnChip ASIC */
 #ifdef MILPLUS
@@ -101,20 +103,17 @@
 	call	doc_cmd
 #endif
 
+	popw	%ds			/* now ds == cs */
 	xorw	%di, %di
 	xorw	%dx, %dx
 read_setup_sects:
 	call	doc_readpage
-	decw	%cs:low_sects
+	decw	low_sects
 	jnz	read_setup_sects
 
 #ifdef DEBUG_BUILD
 		/* Print the kernel version string. */
-	pushw	%ds
-	pushw	%si
 	pushw	%bx
-	pushw	%cs
-	popw	%ds
 	MSG(crlf_string)
 	pushw	%es
 	popw	%ds
@@ -125,33 +124,27 @@
 	popw	%ds
 	MSG(kernel_string)
 	popw	%bx
-	popw	%si
-	popw	%ds
 #endif
 
-	movw	$0x8000, %di	/* Go to 32k from setup base */
-	call	read_high_sects	/* copy the kernel sectors */
+	pushw	%es
 
-	pushw	%cs
-	popw	%ds
+	movw	$0x8000, %di		/* Go to 32k from setup base */
+	call	read_high_sects		/* copy the kernel sectors */
+
+		/* At this point, cx=0 */
 	movw	initrd_sects, %ax
 	orw	%ax, high_sects		/* high_sects was previously 0 */
 	jz	skip_initrd
+	movb	%cl, gdt_dst_mid
 	movw	initrd_start, %ax
-	movw	%ax, gdt_dst_mid
+	movb	%al, gdt_dst_hi
+	movb	%ah, gdt_dst_vhi
 
-	pushw	%si
 	pushw	%bx
 	MSG(initrd_string)
 	popw	%bx
-	popw	%si
-
-	movw	doc_seg, %ds
 
-	call	read_high_sects	/* copy the initrd sectors */
-
-	pushw	%cs
-	popw	%ds
+	call	read_high_sects		/* copy the initrd sectors */
 
 skip_initrd:
 
@@ -164,13 +157,12 @@
 
 	movl	initrd_bytes, %eax
 
-	pushw	%es
 	popw	%ds	/* Now write parameters into setup segment */
 
 	orl	%eax, ramdisk_size  /* ramdisk_size should be 0 before this */
 	jz	skip_initrd2
 	movw	%cs:initrd_start, %ax
-	movw	%ax, ramdisk_image + 1
+	movw	%ax, ramdisk_image + 2	/* initrd_start is 64k aligned */
 skip_initrd2:
 
 		/* Compute the physical address of the commandline and
@@ -206,23 +198,30 @@
 		/* read_high_sects: Read pages from DOC into high memory.
 		   Each page is first loaded into low memory using doc_readpage,
 		   then copied to high memory using int 15h function 87h.
-		   We read cs:high_sects pages (leaving cs:high_sects = 0 when
+		   We read high_sects pages (leaving high_sects = 0 when
 		   we're done.) */
 read_high_sects:
 	call	doc_readpage
-	movw	%cx, %di	/* re-use the same low memory buffer */
-	pushw	%es
+	movw	%ax, %di	/* re-use the same low memory buffer */
 	pushw	%cs
 	popw	%es
-	pushw	%si
 	movw	$gdt, %si
-	movw	$0x200, %cx
+	movw	$0x100, %cx
 	movb	$0x87, %ah
+	stc
 	int	$0x15
-	popw	%si
-	popw	%es
-	addw	$2, %cs:gdt_dst_mid
-	decw	%cs:high_sects
+	jc	highcopy_fail
+	test	%ah, %ah
+	jz	highcopy_ok
+highcopy_fail:
+	pushw	%cs
+	popw	%ds
+	MSG(copyfail_string)
+1:	jmp	1b		/* hang. */
+highcopy_ok:
+	addw	$2, gdt_dst_mid
+	adcb	$0, gdt_dst_vhi
+	decw	high_sects
 	jnz	read_high_sects
 	ret
 /***************************************************************************/
@@ -248,6 +247,10 @@
 	movw	%dx, %ax
 	call	phword
 #endif
+	/* cs must == ds at this point */
+	movw	$SIREG, %si
+	movw	setup_seg, %es
+	movw	doc_seg, %ds
 #ifdef MILPLUS
 		/* Flash command:	Reset */
 	movb	$NAND_CMD_RESET, %al
@@ -299,11 +302,17 @@
 	movsb
 	decw	%si
 	loop	rploop
+	pushw	%cs
+	popw	%ds		/* restore ds == cs */
 	incw	%dx
+	jnz	dx_ok
+	MSG(nodata_string)
+1:	jmp	1b		/* hang. */
+dx_ok:
 	cmpw	$0xb1db, %es:-2(%di)
 	jne	nextpage
 	subw	$8, %di
-	popw	%cx	/* di = old di + 512. Return original di in cx */
+	popw	%ax	/* di = old di + 512. Return original di in ax. cx=0. */
 	ret
 
                 /* doc_cmd:      Send a command to the flash chip */
@@ -335,7 +344,7 @@
 	DOC_DELAY4
                 /* Write the actual command */
 	SLOWIO_WRITE(%al)
-  	movb	%al, SI_CDSN_IO
+  	movb	%al, BX_CDSN_IO		/* Can't use SI_CDSN_IO here! */
 	/* fall through... */
 
                 /* doc_wait:     Wait for the DiskOnChip to be ready */
@@ -428,14 +437,16 @@
 gdt_src_lo:     .byte   0
 gdt_src_mid:    .byte   0x80
 gdt_src_hi:     .byte   0
-gdt_src_perm:   .byte   0x93
-        .word   0
+gdt_src_flags1: .byte   0x93
+gdt_src_flags2: .byte   0
+gdt_src_vhi:    .byte   0
 gdt_dst_limit:  .word   0xffff
 gdt_dst_lo:     .byte   0
 gdt_dst_mid:    .byte   0
 gdt_dst_hi:     .byte   0x10
-gdt_dst_perm:   .byte   0x93
-                .word   0
+gdt_dst_flags1: .byte   0x93
+gdt_dst_flags2: .byte   0
+gdt_dst_vhi:    .byte   0
                 .skip   0x10
 
 #ifdef DEBUG_BUILD
@@ -448,6 +459,9 @@
 done_string:	.string "done.\n\rCommandline: "
 #endif
 
+copyfail_string:.string "COPY TO HIGH MEMORY FAILED"
+failed_string = . - 7
+nodata_string:	.string "CANNOT FIND IMAGE ON DEVICE"
 boot_string:	.string "\n\rBooting!\n\r"
 crlf_string = (. - 3)
 
@@ -506,6 +520,8 @@
 	cmpsb
 	je	skip_install
 
+	pushw	%dx		/* push 0 */
+
 	MSG(installer_string)
 
 #ifdef DEBUG_BUILD
@@ -528,7 +544,24 @@
 	shrw	$4, %ax
 	addw	%ax, gdt_src_mid
 
-
+		/* Memory-size code below adapted from Syslinux */
+	movw	$(0x4000-0x400), %bp	/* 15M in 1k chunks */
+#ifdef DEBUG_BUILD
+	MSG(int15e801_string)
+#endif
+	stc
+	movw	$0xe801, %ax
+	int	$0x15
+	jc	e801_fail
+	cmpw	%bp, %ax
+	jne	e801_fail
+	movw	%bx, %ax	/* now ax = amount of mem -16M, in 64k blocks */
+#ifdef DEBUG_BUILD
+	call	phword
+#endif
+	incb	%ah		/* Add 16M (in 64k blocks) back in. */
+	jmp	got_topmem
+e801_fail:
 #ifdef DEBUG_BUILD
 	MSG(int1588_string)
 #endif
@@ -537,16 +570,18 @@
 #ifdef DEBUG_BUILD
 	call	phword
 #endif
-	cmpw	$(0x4000-0x400), %ax /* safety check: if it's above 15M ... */
-	jbe	topmem_ok
-	movw	$(0x4000-0x400), %ax /* ... replace with 15M. */
-topmem_ok:
-	addw	$0x400, %ax	/* Adjust for 1M offset */
-	shlw	$1, %ax		/* Convert to sectors */
-	subw	initrd_sects, %ax /* Compute start of initrd */
-	shlw	$1, %ax		/* Convert to 256-byte blocks */
-	andw	$0xfff0, %ax	/* Round down to 4k block (req'd by kernel) */
-	movw	%ax, initrd_start	/* Store initrd start for later use */
+	cmpw	%bp, %ax	/* safety check: if it's above 15M ... */
+	jbe	mem_le16meg
+	movw	%bp, %ax	/* ... replace with 15M. */
+mem_le16meg:
+	addw	$0x400, %ax	/* Add 1M (in 1k blocks) back in. */
+	shrw	$6, %ax		/* Convert to 64k blocks (round down) */
+got_topmem:
+	movw	initrd_sects, %bx
+	shrw	$7, %bx		/* Convert to 64k blocks (round down) */
+	incw	%bx		/* Account for the fact that we rounded down. */
+	subw	%bx, %ax	/* Compute start of initrd in 64k blocks */
+	movw	%ax, initrd_start
 #ifdef DEBUG_BUILD
 	pushw	%ax
 	MSG(initrdstart_string)
@@ -563,7 +598,7 @@
 	*/
 
 		/* Find top of low memory */
-	movw	%dx, %ds
+	popw	%ds		/* pop 0 */
 	movw	0x0413, %ax
 #ifdef DEBUG_BUILD
 	call	phword
@@ -617,9 +652,10 @@
 #ifdef DEBUG_BUILD
 docseg_string: .string "doc_seg = 0x"
 setupseg_string: .string "    setup_seg = 0x"
-int1588_string: .string "\n\rint15/88 returns 0x"
+int15e801_string: .string "\n\rint15/e801 returns 0x"
+int1588_string: .string "FAILED\n\rint15/88 returns 0x"
 initrdstart_string: .string "    initrd_start = 0x"
-lowmemtop_string: .string "00\n\rtop of low mem = 0x"
+lowmemtop_string: .string "0000\n\rtop of low mem = 0x"
 handlerseg_string: .string "k    handler seg = 0x"
 presskey_string: .string "\n\r  -- Press any key --\n\r"
 #endif





More information about the linux-mtd-cvs mailing list