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