Module Name: src
Committed By: isaki
Date: Sun Aug 16 06:43:44 UTC 2020
Modified Files:
src/sys/arch/x68k/stand/libiocs: iocscall.h
src/sys/arch/x68k/stand/xxboot: Makefile.xxboot boot.S bootmain.c
consio1.c version xx.c xxboot.h xxboot.ldscript
src/sys/arch/x68k/stand/xxboot/xxboot_ffsv1: Makefile
src/sys/arch/x68k/stand/xxboot/xxboot_ffsv2: Makefile
src/sys/arch/x68k/stand/xxboot/xxboot_lfsv1: Makefile
src/sys/arch/x68k/stand/xxboot/xxboot_lfsv2: Makefile
Added Files:
src/sys/arch/x68k/stand/xxboot: ashldi3.S ashrdi3.S memcmp.S memcpy.S
memset.S
src/sys/arch/x68k/stand/xxboot/fdboot_ustarfs: Makefile
Log Message:
Overhaul xxboot. And merge floppy boot, taken from boot_ustar.
- Rewrite boot.S completely.
boot.S now supports boot from SCSI HD/CD and floppy.
- Use IOCS call to identify the floppy format, instead of chkfmt.s which
accesses hardware directly.
- Import print_hex() debug function from boot_ufs.
- Import a feature that displays initial registers (for debug) from boot_ufs,
and restore it (this in boot_ufs has been broken).
- Add size optimized alternatives for some libkern routines.
- Stop linking libsa to prevent to link unexpected objects.
- Bump version to 2.0.
To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/x68k/stand/libiocs/iocscall.h
cvs rdiff -u -r1.17 -r1.18 src/sys/arch/x68k/stand/xxboot/Makefile.xxboot
cvs rdiff -u -r0 -r1.1 src/sys/arch/x68k/stand/xxboot/ashldi3.S \
src/sys/arch/x68k/stand/xxboot/ashrdi3.S \
src/sys/arch/x68k/stand/xxboot/memcmp.S \
src/sys/arch/x68k/stand/xxboot/memcpy.S \
src/sys/arch/x68k/stand/xxboot/memset.S
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/x68k/stand/xxboot/boot.S
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/x68k/stand/xxboot/bootmain.c
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/x68k/stand/xxboot/consio1.c
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/x68k/stand/xxboot/version \
src/sys/arch/x68k/stand/xxboot/xx.c \
src/sys/arch/x68k/stand/xxboot/xxboot.h
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/x68k/stand/xxboot/xxboot.ldscript
cvs rdiff -u -r0 -r1.1 src/sys/arch/x68k/stand/xxboot/fdboot_ustarfs/Makefile
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/x68k/stand/xxboot/xxboot_ffsv1/Makefile
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/x68k/stand/xxboot/xxboot_ffsv2/Makefile
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/x68k/stand/xxboot/xxboot_lfsv1/Makefile
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/x68k/stand/xxboot/xxboot_lfsv2/Makefile
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/x68k/stand/libiocs/iocscall.h
diff -u src/sys/arch/x68k/stand/libiocs/iocscall.h:1.2 src/sys/arch/x68k/stand/libiocs/iocscall.h:1.3
--- src/sys/arch/x68k/stand/libiocs/iocscall.h:1.2 Sat Jan 18 05:07:34 2020
+++ src/sys/arch/x68k/stand/libiocs/iocscall.h Sun Aug 16 06:43:43 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: iocscall.h,v 1.2 2020/01/18 05:07:34 isaki Exp $ */
+/* $NetBSD: iocscall.h,v 1.3 2020/08/16 06:43:43 isaki Exp $ */
/*
* IOCS call macros for X680x0
@@ -30,6 +30,7 @@
#define __B_CLR_ST 0x2A
#define __B_READ 0x46
#define __B_RECALI 0x47
+#define __B_READID 0x4A
#define __B_DRVCHK 0x4E
#define __BOOTINF 0xFFFFFF8E
#define __JISSFT 0xFFFFFFA1
Index: src/sys/arch/x68k/stand/xxboot/Makefile.xxboot
diff -u src/sys/arch/x68k/stand/xxboot/Makefile.xxboot:1.17 src/sys/arch/x68k/stand/xxboot/Makefile.xxboot:1.18
--- src/sys/arch/x68k/stand/xxboot/Makefile.xxboot:1.17 Fri Aug 14 03:54:46 2020
+++ src/sys/arch/x68k/stand/xxboot/Makefile.xxboot Sun Aug 16 06:43:43 2020
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.xxboot,v 1.17 2020/08/14 03:54:46 isaki Exp $
+# $NetBSD: Makefile.xxboot,v 1.18 2020/08/16 06:43:43 isaki Exp $
NOMAN= # defined
@@ -25,7 +25,12 @@ BINMODE= 444
S= ${.CURDIR}/../../../../..
M= $S/arch/x68k
.PATH: ${.CURDIR}/..
-SRCS= boot.S bootmain.c conf.c consio1.c xx.c
+SRCS= boot.S bootmain.c conf.c xx.c
+SRCS+= ashrdi3.S
+SRCS+= ashldi3.S
+SRCS+= memcpy.S
+SRCS+= memset.S
+SRCS+= memcmp.S
.include "${S}/conf/newvers_stand.mk"
@@ -47,7 +52,7 @@ LINKFLAGS+= --defsym=BOOT_TEXTADDR=$(BO
LINKFLAGS+= --defsym=TEXTDATASIZE=$(TEXTDATASIZE)
LIBIOCS!= cd $M/stand/libiocs && ${PRINTOBJDIR}
LIBSA!= cd $M/stand/libsa && ${PRINTOBJDIR}
-LDLIBS= -L${LIBSA}/lib/sa -lsa -L ${LIBSA}/lib/kern -lkern
+LDLIBS= -L ${LIBSA}/lib/kern -lkern
LDLIBS+= -L${LIBIOCS} -liocs
.PATH: $S/lib/libsa
@@ -57,8 +62,11 @@ CPPFLAGS+= -DLIBSA_NO_FD_CHECKING
CPPFLAGS+= -DLIBSA_NO_FS_WRITE
CPPFLAGS+= -DLIBSA_NO_RAW_ACCESS
CPPFLAGS+= -DLIBSA_NO_TWIDDLE
+CPPFLAGS+= -DUSTAR_SECT_PER_CYL=30
SRCS+= open.c close.c read.c lseek.c loadfile.c loadfile_aout.c alloc.c
+SRCS+= errno.c globals.c
SRCS+= $(FS).c
+SRCS+= ${BOOTSRCS}
.PATH: $M/stand/common
SRCS+= exec_image.S
Index: src/sys/arch/x68k/stand/xxboot/boot.S
diff -u src/sys/arch/x68k/stand/xxboot/boot.S:1.12 src/sys/arch/x68k/stand/xxboot/boot.S:1.13
--- src/sys/arch/x68k/stand/xxboot/boot.S:1.12 Tue Jan 28 12:02:02 2020
+++ src/sys/arch/x68k/stand/xxboot/boot.S Sun Aug 16 06:43:43 2020
@@ -1,8 +1,4 @@
-| file: boot.S
-| author: chapuni([email protected])
-| ITOH Yasufumi
-|
-| $NetBSD: boot.S,v 1.12 2020/01/28 12:02:02 isaki Exp $
+| $NetBSD: boot.S,v 1.13 2020/08/16 06:43:43 isaki Exp $
|
| (1) IPL (or previous stage loader) loads first 1KB of this primary
@@ -14,9 +10,6 @@
| (3) The full primary bootloader loads the secondary bootloader known as
| /boot from its filesystem to 0x6000. And jump to there.
|
-| Therefore, The first 1KB must be relocatable.
-| The first 1KB must be smaller than or equal to 1024 bytes.
-|
| (1) -> (2) -> (3)
| +------------+ +------------+ +------------+ 0x000000
| : : : : : :
@@ -29,6 +22,7 @@
| : : |boot loader | |boot loader |
| : : |(text+data) | |(text+data) |
| : : +------------+ +------------+ 0x005000
+| : : |(startregs) | |(startregs) |
| : : |(bss) | |(bss) |
| : : +------------+ +------------+ 0x006000
| : : : : | /boot |
@@ -40,310 +34,357 @@
| : : :(heap) : :(heap) :
| : : : : : :
|
+| The program code before first_kbyte
+| - must not access any text/data labels after first_kbyte
+| (because it may not be loaded yet).
+| - must access any labels before first_kbyte by PC relative addressing
+| (because this loader is assembled as starting from 0x3000 but is loaded
+| at 0x2000 or 0x2400).
+| - must use RELOC() macro to access bss section (and first_kbyte as a jump
+| destination address).
+|
+| The program code after first_kbyte can access any labels in all sections
+| directly.
#include <machine/asm.h>
#include "iocscall.h"
-#define SCSI_ADHOC_BOOTPART
-
-#define SRAM 0x00ED0000 /* SRAM stat addr */
-#define SRAM_MEMSZ (SRAM + 8) /* (L) size of main memory */
-#define MINMEM 0x00400000 /* at least 4MB required */
+#define RELOC(var) %a5@(((var)-top):W)
#define BOOT_ERROR(s) jbsr boot_error; .asciz s; .even
- .globl _C_LABEL(bootmain)
- .text
+#define minN (0)
+#define minC (1)
+#define minH (2)
+#define minR (3)
+#define maxN (4)
+#define maxC (5)
+#define maxH (6)
+#define maxR (7)
+
+ .globl _C_LABEL(bootmain)
+ .globl _C_LABEL(startregs)
+ .text
+
ASENTRY_NOPROFILE(start)
ASENTRY_NOPROFILE(top)
- bras _ASM_LABEL(entry0)
+ bras entry
.ascii "SHARP/"
.ascii "X680x0"
.word 0x8199,0x94e6,0x82ea,0x82bd
.word 0x8e9e,0x82c9,0x82cd,0x8cbb
.word 0x8ec0,0x93a6,0x94f0,0x8149
- .word 0
-| d4 �ˤϤ��Ǥ� SCSI ID �����äƤ���
-ASENTRY_NOPROFILE(entry0)
- moveml %d0-%d7/%a0-%a7,_C_LABEL(startregs)
- lea TEXTADDR:W,%a5 | set base ptr
-#define _RELOC(adr) %a5@(((adr)-top):W)
-#define ASRELOC(var) _RELOC(_ASM_LABEL(var))
-#define RELOC(var) _RELOC(_C_LABEL(var))
-
- lea RELOC(__bss_start),%a1
- bra _ASM_LABEL(entry)
-
-| Disklabel= 404bytes
-| Since LABELOFFSET in <machine/disklabel.h> is 0x40,
-| entry must be after 0x000001d4 (0x000f01d4)
+msg_progname:
+ | This will be printed on boot_error. And it also roles
+ | a signature in binary dump.
+ | Max length of PROG(without \0) is 14 ("fdboot_ustarfs").
+ .ascii "\r\n\n" | 3
+ .ascii PROG | 14
+ .asciz ": " | 2+1
+ .org msg_progname + 20
+entry:
+ jbra disklabel_end
+
+ | Disklabel must be placed at 0x40 and the size is 404 bytes.
+ | (See LABELOFFSET in <machine/disklabel.h>)
.org 0x40
disklabel:
.space 404
+disklabel_end:
+ | At first save all initial registers for observing traces
+ | of the IPL (or the previous bootloader). At this point
+ | we cannot use RELOC() yet so that use absolute addressing.
+ | To prevent startregs from being cleared by subsequent bss
+ | initialization, we place it out of bss area.
+ moveml %d0-%d7/%a0-%a7,startregs:W
+
+ | Initialize the screen. Some IPL (060turbo ROM or genuine
+ | boot selector) don't initialize the screen. It should be
+ | done as early as possible.
+ moveql #0x10,%d1
+ IOCS(__CRTMOD)
-ASENTRY_NOPROFILE(entry)
- movew #_end-1,%d0 | bss end (low word only)
-
- | clear out bss (must be <= 64KB)
- subw %a1,%d0
-clrbss: clrb %a1@+
+ | Set system stack
+ swap %d1 | %d1 = 0x0010_0000
+ moveal %d1,%sp
+
+ | Set base pointer. Now we can use RELOC() macro.
+ leal TEXTADDR:W,%a5
+
+ | Initialize bss.
+ | This code limits bss less than 64KB but it's no matter.
+ | The bss cannot grow more than 4KB. See xxboot.ldscript.
+ leal RELOC(__bss_start),%a1
+ movew #_end - 1,%d0 | bss end
+
+ subw %a1,%d0 | don't change this op!!
+clrbss: | see chkmpu below
+ clrb %a1@+
dbra %d0,clrbss
- movel %d4,RELOC(ID) | SCSI ID (if booted from SCSI)
-
- lea 0x00100000,%sp | set system stack
- lea %a5@,%a1 | set load address
- | a1 will be used later for IOCS calls
+ | If it boots from SCSI, %d4 has SCSI ID.
+ movel %d4,RELOC(SCSI_ID)
- | we use 68020 instructions, and check MPU beforehand
+chkmpu:
+ | Check MPU beforehand since we want to use 68020 instructions.
+ | Here the above "subw %a1,%d0" = 0x9049 and %d0.w = -1 at this
+ | point, so that subsequent moveb loads
+ | 0x49 if MPU <= 010 (clrbss + %d0.w)
+ | 0x90 if MPU >= 020 (clrbss + %d0.w*2).
+ | This is a MOVE op, not a TST op because TST with pc-relative
+ | is not available on 000/010.
+ moveb %pc@(clrbss-chkmpu-2:B,%d0:W:2),%d0
+ jmi mpuok
+ BOOT_ERROR("MPU 68000?");
+mpuok:
+ |
+ | Check where did I boot from.
|
- | here d0.w = -1, and the above "subw a1,d0" = 0x9049, and
- | if MPU <= 010 loads 0x49,
- | if MPU >= 020 loads 0x90.
- | This is a move, not a tst instruction
- | because pc-relative tsts are not available on 000/010.
-chkmpu: moveb %pc@(clrbss-chkmpu-2:B,%d0:W:2),%d0 | 103B 02xx
- jmi mpuok | MC68020 or later
- BOOT_ERROR("MPU 68000?")
-mpuok: | XXX check for MMU?
-
IOCS(__BOOTINF)
- lsll #8,%d0 | clear MSByte
- lsrl #8,%d0 |
- movel %d0,RELOC(BOOT_INFO)
+ movel %d0,RELOC(BOOT_INFO) | save whole result
+ | %d0 = 0xHHWWWWWW
|
- | 0x80...0x8F SASI
- | 0x90...0x93 Floppy
- | 0xED0000...0xED3FFE SRAM
- | others ROM (SCSI?)
- |
- movel %d0,%d1
- clrb %d1
- tstl %d1
- jne boot_ram_rom
- |
- | SASI or Floppy
- |
- movel %d0,%d2
- andib #0xFC,%d0
- cmpib #0x90,%d0
- jne boot_dev_unsupported | boot from SASI?
- |
- | Floppy
- |
- moveb %d2,%d0
- andib #0x03,%d0 | drive # (head=0)
- jbsr check_fd_format
- moveml %d0-%d1,RELOC(FDSECMINMAX) | min and max sec #
- lslw #8,%d2
- moveq #0x70,%d1
- orw %d2,%d1 | PDA*256 + MODE
+ | HH: how did I boot (powersw or alarm etc)
+ | WWWWWW: where did I boot from
+ | 0x80...0x8f SASI
+ | 0x90...0x93 Floppy
+ | 0xed0000...0xed3ffe SRAM
+ | others ROM (maybe SCSI)
+
+ bfextu %d0{#8:#8},%d1
+ jne boot_rom_ram | ROM or SRAM
+ | FALLTHROUGH | SASI or Floppy
+
+boot_sasi_floppy:
+ | Floppy or SASI
+ cmpiw #0x90,%d0
+ jlt boot_dev_not_supp | SASI
+
+ |
+ | Boot from floppy
+ |
+boot_floppy:
+ | Make PDA+MODE
+ lslw #8,%d0 | %d0=$00009X00 (X is unit#)
+ moveql #0x70,%d1
+ orw %d0,%d1 | %d1=$00009X70 = (PDA<<8)+MODE
movel %d1,RELOC(FDMODE)
- movel %d0,%d2 | read position (first sector)
- movel #8192,%d3 | read bytes
+check_fd_format:
+ | Check fd format.
+ | Obtain min & max sector # of track(cylinder) 0.
+ | On x68k, we can consider only double-sided floppy.
+ moveql #0,%d2
+init_loop:
+ | On 1st time, clear %d3-%d5 with zero.
+ | On 2nd time, initialize %d3-%d5 with first %d2.
+ movel %d2,%d3 | %d3: initial NCHR
+ movel %d2,%d4 | %d4: minimum NCHR
+ movel %d2,%d5 | %d5: maximum NCHR
+loop:
+ | B_READID with MSB of %d2 set obtains detected CHRN to %d2.
+ moveql #1,%d2 | %d2 = 0x00000001
+ rorl #1,%d2 | %d2 = 0x80000000
+ IOCS(__B_READID)
+ | %d2 = 0xCCHHRRNN
+ rorl #8,%d2 | %d2 = 0xNNCCHHRR
+
+ | On 1st time, goto init_loop with %d2 (%d2 is not zero).
+ | On 2nd time, fall through because %d3 is not zero.
+ tstl %d3
+ jeq init_loop
+
+ cmpl %d4,%d2 | if (%d2 < %d4)
+ jge 1f |
+ movel %d2,%d4 | min = %d2
+1:
+ cmpl %d5,%d2 | if (%d2 > %d5)
+ jle 1f |
+ movel %d2,%d5 | max = %d2
+1:
+ cmpl %d3,%d2 | if (%d2 == %d3) break
+ jne loop
+
+ | Assume 2HD
+ oriw #0x0100,%d5 | FDSEC.maxsec.H = 1
+ moveml %d4-%d5,RELOC(FDSEC) | Store
+ | end of check_fd_format
+
+ | read 8KB myself from floppy
+ | %d1: (PDA<<8)+MODE already
+ movel %d4,%d2 | %d2: read pos = first sector
+ moveql #0x20,%d3 | %d3: read bytes = (0x20 << 8)
+ lsll #8,%d3 | = 0x2000 = 8192
+ leal %a5@,%a1 | %a1: dest buffer
IOCS(__B_READ)
- jra boot_read_done
-
-#include "chkfmt.s"
-
-boot_ram_rom:
- movel %d0,%d1
- swap %d1
- cmpiw #0x00ED,%d1
- jne boot_SCSI
- | boot from SRAM?
-
-boot_dev_unsupported:
- BOOT_ERROR("unsupported boot device")
-
-|
-| volatile void BOOT_ERROR(const char *msg);
-| print error message, wait for key press and reboot
-|
-booterr_msg: .asciz "\r\n\n"
-reboot_msg: .asciz "\r\n[Hit key to reboot]"
- .even
-
-ENTRY_NOPROFILE(BOOT_ERROR)
- addql #4,%sp
-boot_error: lea %pc@(booterr_msg),%a1
- IOCS(__B_PRINT)
- moveal %sp@+,%a1
- IOCS(__B_PRINT)
-ENTRY_NOPROFILE(exit)
-ENTRY_NOPROFILE(_rtt)
- lea %pc@(reboot_msg),%a1
- IOCS(__B_PRINT)
-
- | wait for a key press (or release of a modifier)
- IOCS(__B_KEYINP)
-
- | issue software reset
- trap #10
- | NOTREACHED
+ | Jump to full parimary loader
+ jmp RELOC(first_kbyte)
+boot_rom_ram:
+ | ROM(SCSI) or SRAM
+ cmpib #0xed,%d1
+ jeq boot_dev_not_supp | SRAM
|
- | ROM boot ... probably from SCSI
+ | Boot from SCSI
|
-boot_SCSI:
-#ifdef SCSI_ADHOC_BOOTPART
- |
- | Find out boot partition in an ad hoc manner.
- |
-
+boot_scsi:
| get block length of the SCSI disk
- SCSIIOCS(__S_READCAP) | using buffer at a1
+ leal RELOC(SCSI_CAP),%a1
+ SCSIIOCS(__S_READCAP)
tstl %d0
- jeq 1f
+ jeq boot_scsi1
BOOT_ERROR("READCAP failed")
-1: moveq #0,%d5
- moveb %a1@(6),%d5 | 1: 256, 2: 512, 4: 1024, 8: 2048
- lsrb #1,%d5 | 0: 256, 1: 512, 2: 1024, 4: 2048
- movel %d5,RELOC(SCSI_BLKLEN)
-
- | find out the start position of the boot partition
- | XXX VERY AD HOC
+boot_scsi1:
+ movel RELOC(SCSI_CAP+4),%d0 | %d0 = blocksize in bytes
+ lsrl #2,%d0 | %d0 = blocksize in longword
+ moveql #25,%d5
+ bfffo %d0{#0:#32},%d1 | 25:256 24:512 23:1024 22:2048
+ subl %d1,%d5 | 0:256 1:512 2:1024 3:2048
+ movel %d5,RELOC(SCSI_BLKLEN) | %d5 = sector length index
+
+ | Find out the start position of the boot partition.
+ | There seems to be no interface or consensus about this and
+ | so that we would have to do it heuristicly.
|
| ROM firmware:
- | pass read pos (in block #) in d2
- | Human68k-style partition table does not exist
- | d2 is 4 at the maximum
+ | pass read pos (in block #, aka sector #) in %d2.
+ | Human68k-style partition table does not exist.
+ | %d2 is 4 at the maximum.
| SCSI IPLs (genuine and SxSI):
- | pass read pos (in kilobytes) in d2
- | d2 is bigger than 0x20
- | partition table on the memory is destroyed
+ | pass read pos (in kilobytes) in %d2.
+ | %d2 is bigger than 0x20.
+ | partition table on the memory is destroyed.
| BOOT MENU Ver.2.22:
- | passes partition table entry address in a0
- | d2 is cleared to zero
- | No other IPL is supported. XXX FIXME
+ | passes partition table entry address in %a0.
+ | %d2 is cleared to zero
+ | No other IPLs are supported.
+
tstl %d2
- jne sc1
- | no information in d2 -- probably from BOOT MENU
- | a0 points the partiion table entry
- movel %a0@(0x0008),%d2 | in KByte
-sc1: cmpl #0x20,%d2
- jcs sc2
- lsll #8,%d2 | clear MSByte
- lsrl #7,%d2 | in 512 byte block
- divul %d5,%d2 | in sector
-sc2:
- | read entire boot
- moveq #TDSIZE/512,%d3 | size is TDSIZE byte
- divul %d5,%d3 | in sector
- jbsr scsiread | read at %a1
-
- cmpil #5,%d2
- bcc sc3
- movql #0,%d2
-sc3: movel %d2,RELOC(SCSI_PARTTOP)
-#else
- moveq #1,%d5 | 512bytes/sec
- movel %d5,%sp@-
- moveq #8192/512,%d3 | �ɤ߹������祵����
- moveq #0x40,%d2 | ���������Ǥ�(sd*a �Τ�)
- SCSIIOCS(__S_READ)
-#endif
+ jne 1f
+ | If no information in %d2, probably from BOOT MENU.
+ | %a0 points the on-memory partition table entry.
+ movel %a0@(0x0008),%d2 | %d2 = pos in kbyte
+1:
+ moveql #0x20,%d3
+ cmpl %d3,%d2
+ jcs 1f | jump if %d2 > 0x20
+ | SCSI IPL or BOOT MENU.
+ | At this point, %d2 is pos in kbyte in all cases.
+ lsll #8,%d2 | %d2 = pos in longword
+ divul %d0,%d2 | %d2 = pos in sector
+1:
+ | At this point, %d2 is pos in sector in all cases.
+ | TDSIZE = 8192, TDSIZE / 4 = 0x800 = (0x20 << 6).
+ lsll #6,%d3 | %d3 = TDSIZE in longword
+ divul %d0,%d3 | %d0 = TDSIZE in sector
+ | Read full primary bootloader
+ moveal %a5,%a1 | %a1 = dest buffer
+ jbsr scsiread
-boot_read_done:
- jmp first_kbyte
+ | Selected start sector should not <= 4. There should be
+ | partition table. If so, repoints to zero(?).
+ moveql #5,%d0
+ cmpl %d0,%d2
+ bcc 1f
+ moveql #0,%d2
+1:
+ movel %d2,RELOC(SCSI_PARTTOP)
+
+ | Jump to full parimary loader
+ jmp RELOC(first_kbyte)
+
+|
+| scsiread
+| Read SCSI disk using __S_READ as possible. If __S_READ cannot be
+| used (due to read length or offset), use __S_READEXT instead.
+| input:
+| %d2.l: pos in sector
+| %d3.l: len in sector (must be < 65536)
+| %d4.l: target SCSI ID
+| %d5.l: sector length index (0:256, 1:512, 2:1024, 3:2048, ...)
+| %a1.l: buffer address
+| destroy:
+| %d0,%d1
+scsiread:
+ | if (len >= 256 || pos + len >= 0x200000)
+ | use READEXT
+ | else
+ | use READ
-read_error: BOOT_ERROR("read error")
+ moveql #__S_READEXT,%d1
-#undef RELOC /* base register a5 is no longer available */
-#undef ASRELOC
-#undef _RELOC
+ cmpiw #256,%d3
+ jge scsiread_core | if (d3 >= 256) use READEXT
-|
-| read SCSI
-|
-| input: d2.l: pos in sector
-| d3.l: len in sector
-| d4: target SCSI ID
-| d5: sector length (1: 512, 2: 1024, 4: 2048)
-| a1: buffer address
-| destroy:
-| d0, d1, a1
-|
-scsiread:
- moveml %d2-%d3/%d6-%d7/%a2,%sp@-
- | if (pos >= 0x200000 || (len > 255 && pos + len >= 0x200000))
- | use READEXT
- | else
- | use READ
- moveq #0x20,%d0
- swap %d0 | d0.l = 0x00200000
- moveq #0,%d6
- subqb #1,%d6 | d6.l = 255
- movel %d5,%d7
- lsll #8,%d7
- lsll #1,%d7 | d7 = sector length (byte)
- cmpl %d0,%d2
- jcc scsiread_ext
- moveq #__S_READ,%d1
- cmpl %d3,%d6
- jcc scsiread_noext
- subl %d2,%d0 | d0.0 = 0x200000 - pos
- cmpl %d0,%d3 | <= len
- jcs scsiread_noext | no
-
-scsiread_ext: | use READEXT
- extw %d6 | d6.l = 65535
- moveq #__S_READEXT,%d1
-
-scsiread_noext: | use READ
-loop_scsiread:
- | d1: SCSI IOCS call #
- | d6: max sector count at a time
- movel %d3,%a2 | save original len in a2
- cmpl %d3,%d6
- jcc 1f
- movel %d6,%d3
-1: IOCS(__SCSIDRV) | SCSIIOCS(d1)
- tstl %d0
- jne read_error
- movel %d3,%d0
- mulul %d7,%d0
- addl %d0,%a1
- exg %d3,%a2 | restore original len to d3
- addl %a2,%d2 | pos += read count
- subl %a2,%d3 | len -= read count
- jne loop_scsiread
- moveml %sp@+,%d2-%d3/%d6-%d7/%a2
+ movel %d2,%d0
+ addl %d3,%d0 | %d0 = pos + len
+ jcs scsiread_core | if overflow, use READEXT
+ bftst %d0{#0:#11} | if (pos + len >= 0x200000)
+ jne scsiread_core | use REAEXT
+
+ moveql #__S_READ,%d1 | else use READ
+scsiread_core:
+ IOCS(__SCSIDRV)
rts
+boot_dev_not_supp:
+ BOOT_ERROR("not supported device");
+
|
-| The former part must reside in the first 1KB.
+| void __dead BOOT_ERROR(const char *msg);
+| Print an error message, wait for key press, and reboot.
+| Called from C.
+ENTRY_NOPROFILE(BOOT_ERROR)
+ addql #4,%sp | throw away return address
+ | FALLTHROUGH
|
+| BOOT_ERROR(msg)
+| Print an error message, wait for key press, and reboot.
+| Called from asm.
+boot_error:
+ leal %pc@(msg_progname),%a1
+ IOCS(__B_PRINT)
+ moveal %sp@+,%a1
+ IOCS(__B_PRINT)
+ENTRY_NOPROFILE(exit)
+ENTRY_NOPROFILE(_rtt)
+ leal %pc@(msg_reboot),%a1
+ IOCS(__B_PRINT)
+
+ | wait for a key press (or release of a modifier)
+ IOCS(__B_KEYINP)
+
+ | issue software reset
+ trap #10
+ | NOTREACHED
+msg_reboot:
+ .asciz "\r\n[Hit key to reboot]"
+ .even
+
.globl first_kbyte
first_kbyte:
|--------------------------------------------------------------------------
|
-| The latter text+data part is not accessible at the first boot time.
-| PC-relative can be used from here.
-|
- | Initialize the screen here. Some IPL (060turbo ROM or
- | genuine boot selector) don't initialize the screen.
- | Such initialization should be done as early as possible
- | but it's too severe to place it in first_kbyte area.
- | Therefore do it here.
- moveq #0x10,%d1
- IOCS(__CRTMOD)
-
- jmp _C_LABEL(bootmain) | 0x0Fxxxx ������Ǥ椯
-
- .word 0
+#if defined(SELFTEST)
+ jbsr selftest_ashldi3
+ jbsr selftest_ashrdi3
+ jbsr selftest_memcmp
+ jbsr selftest_memmove
+ jbsr selftest_memset
+#endif
-| int badbaddr __P((void *adr));
-| check if the given address is valid for byte read
-| return: 0: valid, 1: not valid
+ jmp _C_LABEL(bootmain)
+ | NOTREACHED
+|
+| uint32_t badbadd(void *addr)
+| returns 1 if reading addr occurs bus error. Otherwise it returns 0.
ENTRY_NOPROFILE(badbaddr)
- lea 0x0008:W,%a1 | MPU Bus Error vector
- moveq #1,%d0
- lea %pc@(badr1),%a0
+ leal 0x0008:W,%a1 | bus error vector
+ moveql #1,%d0
+ leal %pc@(badbaddr1),%a0
movew %sr,%sp@-
oriw #0x0700,%sr | keep out interrupts
movel %a1@,%sp@-
@@ -351,163 +392,118 @@ ENTRY_NOPROFILE(badbaddr)
movel %sp,%d1 | save sp
moveal %sp@(10),%a0
tstb %a0@ | try read...
- moveq #0,%d0 | this is skipped on bus error
-badr1: moveal %d1,%sp | restore sp
+ moveql #0,%d0 | this is skipped on bus error
+badbaddr1:
+ moveal %d1,%sp | restore sp
movel %sp@+,%a1@
movew %sp@+,%sr
rts
-| void RAW_READ __P((void *buf, u_int32_t blkpos, size_t bytelen));
-| inputs:
-| buf: input buffer address
-| blkpos: read start position in the partition in 512byte-blocks
-| bytelen: read length in bytes
-
-Lraw_read_buf=4+(4*11)
-Lraw_read_pos_=Lraw_read_buf+4
-Lraw_read_len=Lraw_read_buf+8
-
-#ifdef SCSI_ADHOC_BOOTPART
-| RAW_READ of physical disk
-ENTRY_NOPROFILE(RAW_READ0)
- moveq #0,%d0
- jra raw_read1
-#endif
-
-ENTRY_NOPROFILE(RAW_READ)
-#ifdef SCSI_ADHOC_BOOTPART
- movel _C_LABEL(SCSI_PARTTOP),%d0
-raw_read1:
-#endif
+|
+| int raw_read(uint32_t blkpos, uint32_t bytelen, void *buf)
+| blkpos: read start position in 512 byte block unit (always?).
+| bytelen: read length in bytes.
+| caller already avoids bytelen == 0 so that no checks here.
+| must be a multiple of sector size on scsi.
+| buf: destination buffer address
+|
+ENTRY_NOPROFILE(raw_read)
+ moveal %sp,%a1
moveml %d2-%d7/%a2-%a6,%sp@-
- moveml %sp@(Lraw_read_buf),%d1-%d3
- movel %d1,%a1
- | d2.l: pos in 512byte-blocks
- | d3.l: length in bytes
- | a1 (=d1): buffer address
-
- lea TEXTADDR:W,%a5 | set base ptr
-#define _RELOC(adr) %a5@(((adr)-top):W)
-#define ASRELOC(var) _RELOC(_ASM_LABEL(var))
-#define RELOC(var) _RELOC(_C_LABEL(var))
-
- tstb _RELOC(_C_LABEL(BOOT_INFO)+1) | simple check. may be incorrect!
- beqs raw_read_floppy
+ moveml %a1@,%d0/%d2-%d3/%a1 | %d0 (return address)
+ | %d2 blkpos
+ | %d3 bytelen
+ | %a1 buf
+ | At this point boot device is either floppy or SCSI.
+ tstb %pc@(BOOT_INFO+1)
+ jeq raw_read_floppy
+ | FALLTHROUGH
raw_read_scsi:
- movel RELOC(ID),%d4 | SCSI ID
-#ifdef SCSI_ADHOC_BOOTPART
- movel RELOC(SCSI_BLKLEN),%d5 | sector size: 0-2
- | XXX length must be sector aligned
- lsrl #8,%d3 | size in 256byte-blocks
- lsrl #1,%d3
- divul %d5,%d3 | size in sector
- beqs read_half | minimal error check
- divul %d5,%d2 | pos in sector
- addl %d0,%d2 | physical pos in sector
-#else
- moveq #1,%d5 | 512bytes/sec
- moveq #9,%d0 | shift count
- addl #511,%d3
- lsrl %d0,%d3
- bcss read_half | minimal error check
+ | %d2 = pos from device top
+ | in 512 bytes/block
+ lsll #1,%d2 | %d2 = in 256 bytes/block
+ movel %pc@(SCSI_BLKLEN),%d5 | %d5 = sector length index
+ lsrl %d5,%d2 | %d2 = pos from device top
+ | in media sector size
- addl #0x40,%d2 | 'a' partition starts here
-#endif
-| jcc 1f
-| BOOT_ERROR("out of seek") | pos exceeds 32bit
-|1:
+ divull %pc@(SCSI_CAP+4),%d0:%d3| %d3 = bytelen / sectsize
+ | %d0 = bytelen % sectsize
+ tstl %d0
+ jeq .Lraw1
+ BOOT_ERROR("Err1") | ASSERT(bytelen%sectsize==0)
+.Lraw1:
+ movel %pc@(SCSI_ID),%d4 | %d4 = SCSI ID
jbsr scsiread
- bras raw_read_end
-raw_read_floppy:
- |
- | Floppy read routine
- |
-
- | convert to seek position
-
- asll #2,%d2 | size in 128byte-blocks
-
- | sec = raw_read_pos (d2)
- | sec >>= 7 + (sector length: 0-3)
-
- lea RELOC(FDSECMINMAX),%a0
- moveq #0,%d1
- moveb %a0@,%d1 | d1: sector length (0-3)
- lsrl %d1,%d2 | d2: pos in sector
- bcss read_half | error check
-
- | trk = sec / (# sectors)
- | sec = sec % (# sectors)
-
- moveb %a0@(7),%d1 | d1: max sector #
- subb %a0@(3),%d1 | - min sector #
- addqb #1,%d1 | d1: # sectors
- divu %d1,%d2 | d2: (sec << 16) | track
-
- | position = (sec length << 24) | (track/2 << 16)
- | | (track%2 << 8) | (min sec # + sec)
-
- movel %a0@,%d0 | d0: (sec len << 24) | min sec #
- lsrw #1,%d2 | d2: (sec << 16) | (track / 2)
- jcc 1f
- bset #8,%d0 | |= (track % 2) << 8
-1: swap %d2 | d2: ((track / 2) << 16) | sec
- addl %d0,%d2 | d2: position
-
- | read
- movel RELOC(FDMODE),%d1 | PDA*256 + MODE
-
- | B_READ (for floppy)
- | d1.w: PDA x 256 + MODE
- | PDA: 0x90 (drive 0) ... 0x93 (drive 3)
- | MODE: bit6: MFM
- | bit5: retry
- | bit4: seek
- | d2.l: position
- | bit31-24: sector length (0: 128, 1: 256, 2: 512, 3: 1K)
- | bit23-16: track # (0-79)
- | bit15-08: side (0 or 1)
- | bit07-00: sector # (1-)
- | d3.l: read bytes
- | a1: read address
- | return:
- | d0: bit 31-24 ST0
- | bit 23-16 ST1
- | bit 15- 8 ST2
- | bit 7- 0 C
- | -1 on parameter error
- | destroy: d0, d2, d3, a1
- IOCS(__B_READ)
- andil #0xf8ffff00,%d0 | check status (must be zero)
- jne read_error
-
-raw_read_end:
- moveml %sp@+,%a2-%a6/%d2-%d7
+raw_read_exit:
+ moveml %sp@+,%d2-%d7/%a2-%a6
rts
-#undef _RELOC /* base register a5 is no longer available */
-#undef ASRELOC
-#undef RELOC
-
-read_half: BOOT_ERROR("read half of block")
+raw_read_floppy:
+ | nhead = FDSEC.maxsec.H - FDSEC.minsec.H + 1
+ | = 2;
+ | nsect = FDSEC.maxsec.R - FDSEC.minsec.R + 1;
+ |
+ | sect = (blkpos % nsect) + FDSEC.minsec.R;
+ | head = ((blkpos / nsect) % nhead) + FDSEC.minsec.H;
+ | cyl = ((blkpos / nsect) / nhead) + FDSEC.minsec.C;
+ |
+ | NCHR = (FDSEC.minsec.N << 24) |
+ | (cyl << 16) |
+ | (head << 8) |
+ | sect;
+
+ | calc nsect.
+ moveql #1,%d0 | %d0 = 1
+ addb %pc@(FDSEC+maxR),%d0 | %d0 = 1 + maxsec.R
+ subb %pc@(FDSEC+minR),%d0 | %d0 = 1 + maxsec.R - minsec.R
+ | = nsect
+
+ | Convert blkpos to N/C/H/R.
+ divuw %d0,%d2 | %d2.hw = blkpos % nsect
+ | %d2.lw = blkpos / nsect
+ | Here, %d2.hw becomes sector number and .lw becomes cyl+head.
+ | %d2.lw = %0000_0000_CCCC_CCCH in binary form. LSB of
+ | (blkpos / nsect) is head number because we support only
+ | double-sided floppy here.
+ | %d2.w = %0000_0000_CCCC_CCCH
+ lslw #7,%d2 | %d2.w = %0CCC_CCCC_H000_0000
+ lsrb #7,%d2 | %d2.w = %0CCC_CCCC_0000_000H
+ | i.e,
+ | %d2 = $00rrCCHH
+ swap %d2 | %d2 = $CCHH00rr
+ lslw #8,%d2 | %d2 = $CCHHrr00
+ | two bytes from odd FDSEC+minR is (minR << 8 | maxN) and
+ | minN == maxN always.
+ addw %pc@(FDSEC+minR),%d2 | %d2 = $CCHHRRNN
+ rorl #8,%d2 | %d2 = $NNCCHHRR
-|
-| global variables
-|
- BSS(ID, 4) | SCSI ID
- BSS(BOOT_INFO, 4) | result of IOCS(__BOOTINF)
- BSS(FDMODE, 4) | Floppy access mode: PDA x 256 + MODE
- BSS(FDSECMINMAX, 8) | +0: (min sector) sector length
- | +1: (min sector) track #
- | +2: (min sector) side
- | +3: (min sector) sector #
- | +4: (max sector) sector length
- | +5: (max sector) track #
- | +6: (max sector) side
- | +7: (max sector) sector #
-#ifdef SCSI_ADHOC_BOOTPART
- BSS(SCSI_PARTTOP, 4) | start sector of boot partition
- BSS(SCSI_BLKLEN ,4) | sector len 0: 256, 1: 512, 2: 1024
-#endif
+ movel %pc@(FDMODE),%d1 | %d1 = PDA+MODE
+ IOCS(__B_READ)
+ andil #0xf8ffff00,%d0 | Check status (must be zero)
+ jeq raw_read_exit
+ BOOT_ERROR("B_READ failed");
+
+|
+| BSS
+|
+ BSS(BOOT_INFO, 4) | whole result of IOCS BOOTINF
+
+ BSS(FDMODE, 4)
+ BSS(FDSEC, 8) | +0: (minN) sector length
+ | +1: (minC) track number
+ | +2: (minH) head
+ | +3: (minR) sector number
+ | +4: (maxN) sector length
+ | +5: (maxC) track number
+ | +6: (maxH) head
+ | +7: (maxR) sector number
+
+ BSS(SCSI_ID, 4) | SCSI ID, if booted from SCSI
+ BSS(SCSI_CAP, 8) | result of SCSI READCAP
+ | +0.L: total number of logical blocks
+ | +4.L: block length in bytes
+ BSS(SCSI_PARTTOP, 4) | top sector # of this partition
+ BSS(SCSI_BLKLEN ,4) | sector length index
+ | 0:256, 1:512, 2:1024, 3:2048, ..
Index: src/sys/arch/x68k/stand/xxboot/bootmain.c
diff -u src/sys/arch/x68k/stand/xxboot/bootmain.c:1.7 src/sys/arch/x68k/stand/xxboot/bootmain.c:1.8
--- src/sys/arch/x68k/stand/xxboot/bootmain.c:1.7 Fri Aug 14 03:43:28 2020
+++ src/sys/arch/x68k/stand/xxboot/bootmain.c Sun Aug 16 06:43:43 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: bootmain.c,v 1.7 2020/08/14 03:43:28 isaki Exp $ */
+/* $NetBSD: bootmain.c,v 1.8 2020/08/16 06:43:43 isaki Exp $ */
/*-
* Copyright (c) 1993, 1994 Takumi Nakamura.
@@ -36,6 +36,7 @@
#include <sys/param.h>
#include <sys/types.h>
#include <machine/bootinfo.h>
+#include <machine/disklabel.h>
#include <lib/libsa/stand.h>
#include <lib/libsa/loadfile.h>
@@ -46,12 +47,26 @@
#define EXSCSI_BDID ((void *)0x00ea0001)
-/* for debug */
-unsigned int startregs[16];
-
static int get_scsi_host_adapter(char *);
+int get_scsi_part(void);
void bootmain(void) __attribute__ ((__noreturn__));
+#if defined(XXBOOT_DEBUG)
+/* Print 'x' as 'width' digit hex number */
+void
+print_hex(unsigned int x, int width)
+{
+
+ if (width > 0) {
+ print_hex(x >> 4, width - 1);
+ x &= 0x0F;
+ if (x > 9)
+ x += 7;
+ IOCS_B_PUTC((unsigned int) '0' + x);
+ }
+}
+#endif
+
/*
* Check the type of SCSI interface
*/
@@ -82,7 +97,8 @@ get_scsi_host_adapter(char *devstr)
} else if (badbaddr(EXSCSI_BDID)) {
ha = (X68K_BOOT_SCSIIF_MHA << 4) | 0;
#ifdef XXBOOT_DEBUG
- *(uint32_t *)devstr = '/' << 24 | 'm' << 16 | 'h' << 8 | 'a';
+ *(uint32_t *)devstr =
+ ('/' << 24) | ('m' << 16) | ('h' << 8) | 'a';
#endif
} else {
ha = (X68K_BOOT_SCSIIF_SPC << 4) | 1;
@@ -94,10 +110,63 @@ get_scsi_host_adapter(char *devstr)
return ha;
}
+#define PARTTBL_TOP (4) /* sector pos of part info in 512byte/sector */
+#define NPART (15) /* total number of Human68k partitions */
+#define MAXPART (6)
+int
+get_scsi_part(void)
+{
+ union {
+ char pad[1024];
+ struct {
+ uint32_t magic; /* 0x5836384b ("X68k") */
+ uint32_t parttotal; /* total block# -1 */
+ uint32_t diskblocks;
+ uint32_t diskblocks2; /* backup? */
+ struct dos_partition parttbl[NPART];
+ } __packed;
+ } partbuf;
+ int i;
+ int part_top;
+
+ /*
+ * Read partition table.
+ * The actual partition table size we want to read is 256 bytes but
+ * raw_read() for SCSI requires bytelen a multiple of sector size
+ * (SCSI_CAP.blocksize). Human68k supports sector size only 256,
+ * 512 and 1024 so that we always use 1024 bytes fixed length buffer.
+ */
+ raw_read(PARTTBL_TOP, SCSI_CAP.blocksize, &partbuf);
+
+ if (partbuf.magic != 0x5836384b/*"X68k"*/) {
+ BOOT_ERROR("Bad Human68k partition table");
+ /* NOTREACHED */
+ }
+
+ /*
+ * SCSI_PARTTOP is top sector # of this partition in sector size
+ * of this device (normally 512 bytes/sector).
+ * part_top is top block # of this partition in 1024 bytes/block.
+ * Human68k partition table uses 1024 bytes/block unit.
+ */
+ part_top = SCSI_PARTTOP >> (2 - SCSI_BLKLEN);
+ for (i = 0; i < MAXPART; i++) {
+ if ((uint32_t)partbuf.parttbl[i].dp_start == part_top)
+ goto found;
+ }
+ BOOT_ERROR("Can't find this partition?");
+ /* NOTREACHED */
+found:
+ /* bsd disklabel's c: means whole disk. Skip it */
+ if (i >= 2)
+ i++;
+ return i;
+}
+
void
bootmain(void)
{
- int bootdev, ha, fd;
+ int bootdev, fd;
char bootdevstr[16];
u_long marks[MARK_MAX];
@@ -106,35 +175,50 @@ bootmain(void)
IOCS_B_PRINT(bootprog_rev);
IOCS_B_PRINT("\r\n");
- ha = get_scsi_host_adapter(bootdevstr);
-#ifdef XXBOOT_DEBUG
- bootdevstr[10] = '0' + (ID & 7);
- bootdevstr[14] = 'a';
+#if defined(XXBOOT_DEBUG)
+ /* Print the initial registers */
+ int i;
+ for (i = 0; i < __arraycount(startregs); i++) {
+ print_hex(startregs[i], 8);
+ IOCS_B_PRINT((i & 7) == 7 ? "\r\n" : " ");
+ }
+ IOCS_B_PRINT("BOOT_INFO ");
+ print_hex(BOOT_INFO, 8);
+ IOCS_B_PRINT("\r\n");
#endif
-#if defined(CDBOOT)
- bootdev = X68K_MAKESCSIBOOTDEV(X68K_MAJOR_CD, ha >> 4, ha & 15,
- ID & 7, 0, 0);
-#elif defined(FDBOOT) || defined(SDBOOT)
if (BINF_ISFD(&BOOT_INFO)) {
/* floppy */
+ int minor;
+ /* fdNa for 1024 bytes/sector, fdNc for 512 bytes/sector */
+ minor = (FDSEC.minsec.N == 3) ? 0 : 2;
+ bootdev = X68K_MAKEBOOTDEV(X68K_MAJOR_FD, BOOT_INFO & 3, minor);
#ifdef XXBOOT_DEBUG
*(uint32_t *)bootdevstr =
('f' << 24) | ('d' << 16) | ('@' << 8) |
('0' + (BOOT_INFO & 3));
- bootdevstr[4] = '\0';
+ bootdevstr[4] = 'a' + minor;
+ bootdevstr[5] = '\0';
#endif
- /* fdNa for 1024 bytes/sector, fdNc for 512 bytes/sector */
- bootdev = X68K_MAKEBOOTDEV(X68K_MAJOR_FD, BOOT_INFO & 3,
- (FDSECMINMAX.minsec.N == 3) ? 0 : 2);
} else {
/* SCSI */
- bootdev = X68K_MAKESCSIBOOTDEV(X68K_MAJOR_SD, ha >> 4, ha & 15,
- ID & 7, 0, 0 /* XXX: assume partition a */);
- }
+ int major, ha, part;
+ ha = get_scsi_host_adapter(bootdevstr);
+ part = 0;
+#if defined(CDBOOT)
+ major = X68K_MAJOR_CD;
#else
- bootdev = 0;
+ major = X68K_MAJOR_SD;
+ if (SCSI_PARTTOP != 0)
+ part = get_scsi_part();
+#endif
+ bootdev = X68K_MAKESCSIBOOTDEV(major, ha >> 4, ha & 15,
+ SCSI_ID & 7, 0, part);
+#ifdef XXBOOT_DEBUG
+ bootdevstr[10] = '0' + (SCSI_ID & 7);
+ bootdevstr[14] = 'a' + part;
#endif
+ }
#ifdef XXBOOT_DEBUG
IOCS_B_PRINT("boot device: ");
@@ -143,9 +227,17 @@ bootmain(void)
IOCS_B_PRINT("\r\n");
marks[MARK_START] = BOOT_TEXTADDR;
+
+#if defined(XXBOOT_USTARFS)
+ /* ustarfs requires mangled filename... */
+ fd = loadfile("USTAR.volsize.4540", marks,
+ LOAD_TEXT|LOAD_DATA|LOAD_BSS);
+#else
+ /* XXX what is x68k/boot? */
fd = loadfile("x68k/boot", marks, LOAD_TEXT|LOAD_DATA|LOAD_BSS);
if (fd < 0)
fd = loadfile("boot", marks, LOAD_TEXT|LOAD_DATA|LOAD_BSS);
+#endif
if (fd >= 0) {
close(fd);
exec_image(BOOT_TEXTADDR, /* image loaded at */
Index: src/sys/arch/x68k/stand/xxboot/consio1.c
diff -u src/sys/arch/x68k/stand/xxboot/consio1.c:1.1 src/sys/arch/x68k/stand/xxboot/consio1.c:1.2
--- src/sys/arch/x68k/stand/xxboot/consio1.c:1.1 Tue Mar 20 13:01:32 2012
+++ src/sys/arch/x68k/stand/xxboot/consio1.c Sun Aug 16 06:43:43 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: consio1.c,v 1.1 2012/03/20 13:01:32 minoura Exp $ */
+/* $NetBSD: consio1.c,v 1.2 2020/08/16 06:43:43 isaki Exp $ */
/*
* Copyright (c) 2001,2010 MINOURA Makoto.
@@ -29,10 +29,8 @@
#include <lib/libkern/libkern.h>
#include <lib/libsa/stand.h>
-#include "libx68k.h"
-
+#include "xxboot.h"
#include "iocs.h"
-#include "consio.h"
int
getchar(void)
Index: src/sys/arch/x68k/stand/xxboot/version
diff -u src/sys/arch/x68k/stand/xxboot/version:1.3 src/sys/arch/x68k/stand/xxboot/version:1.4
--- src/sys/arch/x68k/stand/xxboot/version:1.3 Sat Jan 18 05:07:34 2020
+++ src/sys/arch/x68k/stand/xxboot/version Sun Aug 16 06:43:43 2020
@@ -1,4 +1,4 @@
-$NetBSD: version,v 1.3 2020/01/18 05:07:34 isaki Exp $
+$NetBSD: version,v 1.4 2020/08/16 06:43:43 isaki Exp $
NOTE ANY CHANGES YOU MAKE TO THE BOOTBLOCKS HERE. The format of this
file is important - make sure the entries are appended on end, last item
@@ -7,3 +7,4 @@ is taken as the current.
1.0: Initial revision.
1.1: Fix FFS and LFS boot from SCSI HD and floppies. Always print version.
1.2: Initialize the screen.
+2.0: Rewrite mostly. Support xxboot_ustarfs.
Index: src/sys/arch/x68k/stand/xxboot/xx.c
diff -u src/sys/arch/x68k/stand/xxboot/xx.c:1.3 src/sys/arch/x68k/stand/xxboot/xx.c:1.4
--- src/sys/arch/x68k/stand/xxboot/xx.c:1.3 Fri Aug 14 03:34:22 2020
+++ src/sys/arch/x68k/stand/xxboot/xx.c Sun Aug 16 06:43:43 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: xx.c,v 1.3 2020/08/14 03:34:22 isaki Exp $ */
+/* $NetBSD: xx.c,v 1.4 2020/08/16 06:43:43 isaki Exp $ */
/*
* Copyright (c) 2010 MINOURA Makoto.
@@ -29,6 +29,7 @@
#include <lib/libsa/stand.h>
#include "xxboot.h"
+#include "iocs.h"
int
xxopen(struct open_file *f, ...)
@@ -49,7 +50,24 @@ xxstrategy(void *arg, int rw, daddr_t db
void *buf, size_t *rsize)
{
- RAW_READ(buf, (uint32_t)dblk, size);
+ /*
+ * dblk is (always?) in 512 bytes unit, even if CD (2048 byte/sect).
+ * size is in byte.
+ *
+ * On SCSI HD, the position specified in raw_read() (1st argument)
+ * counts from the beginning of the disk, not the beginning of the
+ * partition. On SCSI CD and floppy, SCSI_PARTTOP is zero.
+ */
+#if defined(XXBOOT_DEBUG)
+ IOCS_B_PRINT("xxstrategy ");
+ print_hex(dblk, 8);
+ IOCS_B_PRINT(" len=");
+ print_hex(size, 8);
+ IOCS_B_PRINT("\r\n");
+#endif
+ if (size != 0) {
+ raw_read((uint32_t)(SCSI_PARTTOP + dblk), (uint32_t)size, buf);
+ }
if (rsize)
*rsize = size;
return 0;
Index: src/sys/arch/x68k/stand/xxboot/xxboot.h
diff -u src/sys/arch/x68k/stand/xxboot/xxboot.h:1.3 src/sys/arch/x68k/stand/xxboot/xxboot.h:1.4
--- src/sys/arch/x68k/stand/xxboot/xxboot.h:1.3 Fri Aug 14 03:34:22 2020
+++ src/sys/arch/x68k/stand/xxboot/xxboot.h Sun Aug 16 06:43:43 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: xxboot.h,v 1.3 2020/08/14 03:34:22 isaki Exp $ */
+/* $NetBSD: xxboot.h,v 1.4 2020/08/16 06:43:43 isaki Exp $ */
/*
* Copyright (C) 2020 Tetsuya Isaki. All rights reserved.
@@ -28,24 +28,41 @@
#define BINF_ISFD(pbinf) (*((uint8_t *)(pbinf) + 1) == 0)
/* boot.S */
-extern void RAW_READ(void *, uint32_t, size_t);
+extern int raw_read(uint32_t, uint32_t, void *);
extern int badbaddr(volatile void *);
-extern unsigned int BOOT_INFO; /* result of IOCS(__BOOTINF) */
-extern unsigned int ID; /* target SCSI ID */
+extern void BOOT_ERROR(const char *) __dead;
+extern uint32_t BOOT_INFO; /* result of IOCS(__BOOTINF) */
+extern uint32_t SCSI_ID; /* target SCSI ID */
+extern uint32_t SCSI_PARTTOP; /* top sector # of this partition */
+extern uint32_t SCSI_BLKLEN; /* sector length index */
+extern struct {
+ uint32_t total_blocks;
+ uint32_t blocksize;
+} SCSI_CAP;
extern struct {
struct fdfmt{
- uint8_t N; /* sector length 0: 128, ..., 3: 1K */
+ uint8_t N; /* sector length 1:256, 2:512, 3:1024 */
uint8_t C; /* cylinder # */
uint8_t H; /* head # */
uint8_t R; /* sector # */
} minsec, maxsec;
-} FDSECMINMAX; /* FD format type of the first track */
+} FDSEC; /* FD format type of the first track */
+
+/* bootmain.c */
+extern void print_hex(u_int, int);
+
+/* consio1.c */
+extern int getchar(void);
+extern void putchar(int);
/* xx.c */
extern int xxopen(struct open_file *, ...);
extern int xxclose(struct open_file *);
extern int xxstrategy(void *, int, daddr_t, size_t, void *, size_t *);
+/* xxboot.ldscript */
+extern uint32_t startregs[16];
+
/* vers.c */
extern const char bootprog_name[];
extern const char bootprog_rev[];
Index: src/sys/arch/x68k/stand/xxboot/xxboot.ldscript
diff -u src/sys/arch/x68k/stand/xxboot/xxboot.ldscript:1.9 src/sys/arch/x68k/stand/xxboot/xxboot.ldscript:1.10
--- src/sys/arch/x68k/stand/xxboot/xxboot.ldscript:1.9 Fri Aug 14 03:54:46 2020
+++ src/sys/arch/x68k/stand/xxboot/xxboot.ldscript Sun Aug 16 06:43:43 2020
@@ -40,6 +40,11 @@ SECTIONS
_edata = .;
}
. = TEXTADDR + TEXTDATASIZE;
+
+ /* Place uint32_t startregs[16] out of bss */
+ PROVIDE(startregs = .);
+ . += 0x40/* sizeof(startregs) */;
+
.bss :
{
__bss_start = .;
Index: src/sys/arch/x68k/stand/xxboot/xxboot_ffsv1/Makefile
diff -u src/sys/arch/x68k/stand/xxboot/xxboot_ffsv1/Makefile:1.5 src/sys/arch/x68k/stand/xxboot/xxboot_ffsv1/Makefile:1.6
--- src/sys/arch/x68k/stand/xxboot/xxboot_ffsv1/Makefile:1.5 Fri Aug 14 03:40:47 2020
+++ src/sys/arch/x68k/stand/xxboot/xxboot_ffsv1/Makefile Sun Aug 16 06:43:44 2020
@@ -1,7 +1,6 @@
-# $NetBSD: Makefile,v 1.5 2020/08/14 03:40:47 isaki Exp $
+# $NetBSD: Makefile,v 1.6 2020/08/16 06:43:44 isaki Exp $
FS= ffsv1
-BOOTCPPFLAGS= -DSDBOOT -DFDBOOT
TOUCHPROG= @true
Index: src/sys/arch/x68k/stand/xxboot/xxboot_ffsv2/Makefile
diff -u src/sys/arch/x68k/stand/xxboot/xxboot_ffsv2/Makefile:1.5 src/sys/arch/x68k/stand/xxboot/xxboot_ffsv2/Makefile:1.6
--- src/sys/arch/x68k/stand/xxboot/xxboot_ffsv2/Makefile:1.5 Fri Aug 14 03:40:47 2020
+++ src/sys/arch/x68k/stand/xxboot/xxboot_ffsv2/Makefile Sun Aug 16 06:43:44 2020
@@ -1,7 +1,6 @@
-# $NetBSD: Makefile,v 1.5 2020/08/14 03:40:47 isaki Exp $
+# $NetBSD: Makefile,v 1.6 2020/08/16 06:43:44 isaki Exp $
FS= ffsv2
-BOOTCPPFLAGS= -DSDBOOT -DFDBOOT
TOUCHPROG= @true
Index: src/sys/arch/x68k/stand/xxboot/xxboot_lfsv1/Makefile
diff -u src/sys/arch/x68k/stand/xxboot/xxboot_lfsv1/Makefile:1.5 src/sys/arch/x68k/stand/xxboot/xxboot_lfsv1/Makefile:1.6
--- src/sys/arch/x68k/stand/xxboot/xxboot_lfsv1/Makefile:1.5 Fri Aug 14 03:40:47 2020
+++ src/sys/arch/x68k/stand/xxboot/xxboot_lfsv1/Makefile Sun Aug 16 06:43:44 2020
@@ -1,7 +1,6 @@
-# $NetBSD: Makefile,v 1.5 2020/08/14 03:40:47 isaki Exp $
+# $NetBSD: Makefile,v 1.6 2020/08/16 06:43:44 isaki Exp $
FS= lfsv1
-BOOTCPPFLAGS= -DSDBOOT -DFDBOOT
TOUCHPROG= @true
Index: src/sys/arch/x68k/stand/xxboot/xxboot_lfsv2/Makefile
diff -u src/sys/arch/x68k/stand/xxboot/xxboot_lfsv2/Makefile:1.5 src/sys/arch/x68k/stand/xxboot/xxboot_lfsv2/Makefile:1.6
--- src/sys/arch/x68k/stand/xxboot/xxboot_lfsv2/Makefile:1.5 Fri Aug 14 03:40:47 2020
+++ src/sys/arch/x68k/stand/xxboot/xxboot_lfsv2/Makefile Sun Aug 16 06:43:44 2020
@@ -1,7 +1,6 @@
-# $NetBSD: Makefile,v 1.5 2020/08/14 03:40:47 isaki Exp $
+# $NetBSD: Makefile,v 1.6 2020/08/16 06:43:44 isaki Exp $
FS= lfsv2
-BOOTCPPFLAGS= -DSDBOOT -DFDBOOT
TOUCHPROG= @true
Added files:
Index: src/sys/arch/x68k/stand/xxboot/ashldi3.S
diff -u /dev/null src/sys/arch/x68k/stand/xxboot/ashldi3.S:1.1
--- /dev/null Sun Aug 16 06:43:44 2020
+++ src/sys/arch/x68k/stand/xxboot/ashldi3.S Sun Aug 16 06:43:43 2020
@@ -0,0 +1,121 @@
+/* $NetBSD: ashldi3.S,v 1.1 2020/08/16 06:43:43 isaki Exp $ */
+
+/*
+ * Copyright (C) 2020 Tetsuya Isaki. All rights reserved.
+ * Copyright (C) 2020 Y.Sugahara (moveccr). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Size optimized version for primary bootloader.
+ */
+
+#include <machine/asm.h>
+
+ASENTRY_NOPROFILE(__ashldi3)
+ moveml %sp@(4),%d0-%d1/%a0 | %d0:%d1 = quad value
+ | %a0 = shift count
+ jbra start
+loop:
+ lsll #1,%d1 | X:%d1 =<< 1
+ roxll #1,%d0 | %d0:X =<< 1
+start:
+ subql #1,%a0 | sub %a0 doesn't affect ccr,
+ tstl %a0 | but this extra TST op is
+ | smaller than push/pop %d2.
+ jpl loop
+ rts
+
+
+#if defined(SELFTEST)
+#include "iocscall.h"
+ .macro PRINT msg
+ leal \msg,%a1
+ IOCS(__B_PRINT)
+ .endm
+
+ .macro TEST name
+ leal \name,%a2
+ jbsr test
+ .endm
+
+ASENTRY_NOPROFILE(selftest_ashldi3)
+ moveml %d2-%d7/%a2-%a6,%sp@-
+ PRINT %pc@(msg_testname)
+
+ TEST test0
+ TEST test1
+ TEST test2
+ TEST test63
+
+ PRINT %pc@(msg_crlf)
+ moveml %sp@+,%d2-%d7/%a2-%a6
+ rts
+
+test:
+ moveml %a2@+,%d0-%d2 | %d0:%d1 = value
+ | %d2 = count
+ moveml %d0-%d2,%sp@-
+ jbsr __ashldi3
+ leal %sp@(12),%sp
+
+ cmpl %a2@+,%d0 | compare high word
+ jne fail
+ cmpl %a2@+,%d1 | compare low word
+ jne fail
+ PRINT %pc@(msg_ok)
+ rts
+fail:
+ PRINT %pc@(msg_fail)
+ rts
+
+test0: | count = 0
+ .long 0x11223344, 0x55667788
+ .long 0
+ .long 0x11223344, 0x55667788
+
+test1: | count = 1
+ .long 0x11223344, 0x55667788
+ .long 1
+ .long 0x22446688, 0xaaccef10
+
+test2: | count = 2
+ .long 0x11223344, 0x55667788
+ .long 2
+ .long 0x4488cd11, 0x5599de20
+
+test63: | count = 63
+ .long 0x11223344, 0x55667789
+ .long 63
+ .long 0x80000000, 0x00000000
+
+msg_testname:
+ .asciz "__ashldi3"
+msg_ok:
+ .asciz " ok"
+msg_fail:
+ .asciz " fail"
+msg_crlf:
+ .asciz "\r\n"
+
+#endif
Index: src/sys/arch/x68k/stand/xxboot/ashrdi3.S
diff -u /dev/null src/sys/arch/x68k/stand/xxboot/ashrdi3.S:1.1
--- /dev/null Sun Aug 16 06:43:44 2020
+++ src/sys/arch/x68k/stand/xxboot/ashrdi3.S Sun Aug 16 06:43:43 2020
@@ -0,0 +1,139 @@
+/* $NetBSD: ashrdi3.S,v 1.1 2020/08/16 06:43:43 isaki Exp $ */
+
+/*
+ * Copyright (C) 2020 Tetsuya Isaki. All rights reserved.
+ * Copyright (C) 2020 Y.Sugahara (moveccr). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Size optimized version for primary bootloader.
+ */
+
+#include <machine/asm.h>
+
+ASENTRY_NOPROFILE(__ashrdi3)
+ moveml %sp@(4),%d0-%d1/%a0 | %d0:%d1 = quad value
+ | %a0 = shift count
+ jbra start
+loop:
+ asrl #1,%d0 | %d0:X >>>= 1
+ roxrl #1,%d1 | X:%d1 >>= 1
+start:
+ subql #1,%a0 | sub %a0 doesn't affect ccr,
+ tstl %a0 | but this extra TST op is
+ | smaller than push/pop %d2.
+ jpl loop
+ rts
+
+
+#if defined(SELFTEST)
+#include "iocscall.h"
+ .macro PRINT msg
+ leal \msg,%a1
+ IOCS(__B_PRINT)
+ .endm
+
+ .macro TEST name
+ leal \name,%a2
+ jbsr test
+ .endm
+
+ASENTRY_NOPROFILE(selftest_ashrdi3)
+ moveml %d2-%d7/%a2-%a6,%sp@-
+ PRINT %pc@(msg_testname)
+
+ TEST test0
+ TEST test1p
+ TEST test1m
+ TEST test4p
+ TEST test4m
+ TEST test63p
+ TEST test63m
+
+ PRINT %pc@(msg_crlf)
+ moveml %sp@+,%d2-%d7/%a2-%a6
+ rts
+
+test:
+ moveml %a2@+,%d0-%d2 | %d0:%d1 = value
+ | %d2 = count
+ moveml %d0-%d2,%sp@-
+ jbsr __ashrdi3
+ leal %sp@(12),%sp
+
+ cmpl %a2@+,%d0 | compare high word
+ jne fail
+ cmpl %a2@+,%d1 | compare low word
+ jne fail
+ PRINT %pc@(msg_ok)
+ rts
+fail:
+ PRINT %pc@(msg_fail)
+ rts
+
+test0: | count = 0
+ .long 0x11223344, 0x55667788
+ .long 0
+ .long 0x11223344, 0x55667788
+
+test1p: | count = 1
+ .long 0x11223344, 0x55667788
+ .long 1
+ .long 0x089119a2, 0x2ab33bc4
+
+test1m: | count = 1 (negative value)
+ .long 0x91223344, 0x55667788
+ .long 1
+ .long 0xc89119a2, 0x2ab33bc4
+
+test4p: | count = 4
+ .long 0x11223344, 0x55667788
+ .long 4
+ .long 0x01122334, 0x45566778
+
+test4m: | count = 4 (negative value)
+ .long 0x91223344, 0x55667788
+ .long 4
+ .long 0xf9122334, 0x45566778
+
+test63p: | count = 63
+ .long 0x41223344, 0x55667788
+ .long 63
+ .long 0x00000000, 0x00000000
+
+test63m: | count = 63 (negative value)
+ .long 0x91223344, 0x55667788
+ .long 63
+ .long 0xffffffff, 0xffffffff
+
+msg_testname:
+ .asciz "__ashrdi3"
+msg_ok:
+ .asciz " ok"
+msg_fail:
+ .asciz " fail"
+msg_crlf:
+ .asciz "\r\n"
+
+#endif
Index: src/sys/arch/x68k/stand/xxboot/memcmp.S
diff -u /dev/null src/sys/arch/x68k/stand/xxboot/memcmp.S:1.1
--- /dev/null Sun Aug 16 06:43:44 2020
+++ src/sys/arch/x68k/stand/xxboot/memcmp.S Sun Aug 16 06:43:43 2020
@@ -0,0 +1,150 @@
+/* $NetBSD: memcmp.S,v 1.1 2020/08/16 06:43:43 isaki Exp $ */
+
+/*
+ * Copyright (C) 2020 Tetsuya Isaki. All rights reserved.
+ * Copyright (C) 2020 Y.Sugahara (moveccr). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Size optimized (but slow) version for primary bootloader.
+ */
+
+#include <machine/asm.h>
+
+|
+| int memcmp(const void *b1, const void *b2, size_t len)
+|
+ASENTRY_NOPROFILE(memcmp)
+ moveml %sp@,%d0-%d1/%a0-%a1 | %d0: (return address)
+ | %d1: b1
+ | %a0: b2
+ | %a1: len
+
+ exg %d1,%a1 | %d1: len
+ | %a0: b2
+ | %a1: b1
+ moveql #0,%d0
+loop:
+ subql #1,%d1 | if (--len < 0)
+ jcs exit | goto exit
+compare:
+ cmpmb %a0@+,%a1@+
+ jeq loop
+ | To comply with standards, recalc exact return value.
+ | Although everyone expects only 0 or not...
+ moveq #0,%d1
+ moveb %a1@-,%d0
+ moveb %a0@-,%d1
+ subl %d1,%d0 | (uint)*b1 - (uint)*b2
+exit:
+ rts
+
+
+#if defined(SELFTEST)
+#include "iocscall.h"
+ .macro PRINT msg
+ leal \msg,%a1
+ IOCS(__B_PRINT)
+ .endm
+
+ .macro TEST name
+ leal \name,%a2
+ jbsr test
+ .endm
+
+ASENTRY_NOPROFILE(selftest_memcmp)
+ moveml %d2-%d7/%a2-%a6,%sp@-
+ PRINT %pc@(msg_testname)
+
+ TEST test1
+ TEST test2
+ TEST test3
+ TEST test4
+ TEST test5
+
+ PRINT %pc@(msg_crlf)
+ moveml %sp@+,%d2-%d7/%a2-%a6
+ rts
+
+test:
+ movel %a2@+,buf:W | contents of b1
+ movel %a2@+,(buf+4):W | contents of b2
+ movel %a2@+,%sp@- | push len
+ peal (buf+4):W | push b2
+ peal (buf):W | push b1
+ jbsr memcmp
+ leal %sp@(12),%sp
+
+ cmpl %a2@,%d0 | compare return value
+ jne fail
+ PRINT %pc@(msg_ok)
+ rts
+fail:
+ PRINT %pc@(msg_fail)
+ rts
+
+test1:
+ | b1 == b2 within length
+ .long 0x11223344 | b1
+ .long 0x11223355 | b2
+ .long 3 | len
+ .long 0 | expected
+
+test2:
+ | b1 > b2 before the last
+ .long 0x11813344 | b1
+ .long 0x11013344 | b2
+ .long 3 | len
+ .long 0x00000080 | expected
+
+test3:
+ | b1 < b2 in the last byte
+ .long 0x11220044 | b1
+ .long 0x11220144 | b2
+ .long 3 | len
+ .long -1 | expected
+
+test4: | len == 0
+ .long 0x11223344 | b1
+ .long 0x11223344 | b2
+ .long 0 | len
+ .long 0 | expected
+
+test5: | *b1 - *b2 = 0 - 255 = -255
+ .long 0x00000000 | b1
+ .long 0xff000000 | b2
+ .long 1 | len
+ .long -255 | expected
+
+msg_testname:
+ .asciz "memcmp"
+msg_ok:
+ .asciz " ok"
+msg_fail:
+ .asciz " fail"
+msg_crlf:
+ .asciz "\r\n"
+
+ BSS(buf, 8)
+#endif
Index: src/sys/arch/x68k/stand/xxboot/memcpy.S
diff -u /dev/null src/sys/arch/x68k/stand/xxboot/memcpy.S:1.1
--- /dev/null Sun Aug 16 06:43:44 2020
+++ src/sys/arch/x68k/stand/xxboot/memcpy.S Sun Aug 16 06:43:43 2020
@@ -0,0 +1,181 @@
+/* $NetBSD: memcpy.S,v 1.1 2020/08/16 06:43:43 isaki Exp $ */
+
+/*
+ * Copyright (C) 2020 Tetsuya Isaki. All rights reserved.
+ * Copyright (C) 2020 Y.Sugahara (moveccr). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Size optimized (but slow) version for primary bootloader.
+ */
+
+#include <machine/asm.h>
+
+|
+| void bcopy(const void *src, void *dst, size_t len);
+|
+ASENTRY_NOPROFILE(bcopy)
+ moveml %sp@,%d0-%d1/%a0-%a1 | %d0: (return address)
+ | %d1: src
+ | %a0: dst
+ | %a1: count
+ jbra memmove_common
+|
+| void *memcpy(void *dst, const void *src, size_t count);
+| void *memmove(void *dst, const void *src, size_t count);
+|
+ASENTRY_NOPROFILE(memcpy)
+ASENTRY_NOPROFILE(memmove)
+ moveml %sp@,%d0-%d1/%a0-%a1 | %d0: (return address)
+ | %d1: dst
+ | %a0: src
+ | %a1: count
+
+ exg %d1,%a0 | %d1: src
+ | %a0: dst
+ | %a1: count
+memmove_common:
+ exg %d1,%a1 | %d1: count
+ | %a0: dst
+ | %a1: src
+ moveql #0,%d0
+ | %d0: offset in forward mode.
+ | %d1: offset in backward mode
+ | and also loop counter.
+ jbra 2f
+loop:
+ | if src(=%a1) > dst(=%a0), then this is forward copy,
+ | %d0 is already forward offset.
+ | Otherwise backward copy. Copy %d1(backward offset) to %d0.
+ cmpl %a1,%a0
+ jcs 1f
+ movel %d1,%d0
+1:
+ moveb %a1@(%d0.l),%a0@(%d0.l) | %d0: offset
+ addql #1,%d0 | increment forward counter,
+ | though it's pointless in
+ | backward mode
+2:
+ subql #1,%d1 | if (--count < 0)
+ jcc loop | goto exit
+exit:
+ rts | %a0 holds return value (=dst)
+
+
+#if defined(SELFTEST)
+#include "iocscall.h"
+ .macro PRINT msg
+ leal \msg,%a1
+ IOCS(__B_PRINT)
+ .endm
+
+ .macro TEST name
+ leal \name,%a2
+ jbsr test
+ .endm
+
+ASENTRY_NOPROFILE(selftest_memmove)
+ moveml %d2-%d7/%a2-%a6,%sp@-
+ PRINT %pc@(msg_testname)
+
+ TEST test1
+ TEST test2
+ TEST test3
+ TEST test4
+
+ PRINT %pc@(msg_crlf)
+ moveml %sp@+,%d2-%d7/%a2-%a6
+ rts
+
+test:
+ movel %a2@+,buf:W | initial contents of buffer
+ movew %a2@+,(buf+4):W | (6 bytes total)
+ movel %a2@+,%sp@- | push len
+ movel %a2@+,%sp@- | push src
+ movel %a2@+,%a3 | keep dst and
+ movel %a3,%sp@- | push dst
+ jbsr memmove
+ leal %sp@(12),%sp
+
+ cmpal %a3,%a0 | compare return value
+ jne fail
+ movel %a2@+,%d0 | compare buf[0..3]
+ cmpl buf:W,%d0
+ jne fail
+ movew %a2@+,%d0 | compare buf[4..5]
+ cmpw (buf+4):W,%d0 | compare buf[4..5]
+ jne fail
+ PRINT %pc@(msg_ok)
+ rts
+fail:
+ PRINT %pc@(msg_fail)
+ rts
+
+test1:
+ | src=buf+1: 1 2 3 4 5 6
+ | \ \
+ | dst=buf+2: 1 2 2 3 5 6
+ .byte 1, 2, 3, 4, 5, 6 | initial buf
+ .long 2 | len
+ .long buf+1 | src
+ .long buf+2 | dst
+ .byte 1, 2, 2, 3, 5, 6 | expected buf
+
+test2:
+ | src=buf+2: 1 2 3 4 5 6
+ | / /
+ | dst=buf+1: 1 3 4 4 5 6
+ .byte 1, 2, 3, 4, 5, 6 | initial buf
+ .long 2 | len
+ .long buf+2 | src
+ .long buf+1 | dst
+ .byte 1, 3, 4, 4, 5, 6 | expected buf
+
+test3:
+ | src == dst
+ .byte 1, 2, 3, 4, 5, 6 | initial buf
+ .long 2 | len
+ .long buf+1 | src
+ .long buf+1 | dst
+ .byte 1, 2, 3, 4, 5, 6 | expected buf
+
+test4:
+ | len == 0
+ .byte 1, 2, 3, 4, 5, 6 | initial buf
+ .long 0 | len
+ .long buf+1 | src
+ .long buf+1 | dst
+ .byte 1, 2, 3, 4, 5, 6 | expected buf
+
+msg_testname:
+ .asciz "memmove"
+msg_ok:
+ .asciz " ok"
+msg_fail:
+ .asciz " fail"
+msg_crlf:
+ .asciz "\r\n"
+
+ BSS(buf, 8)
+#endif
Index: src/sys/arch/x68k/stand/xxboot/memset.S
diff -u /dev/null src/sys/arch/x68k/stand/xxboot/memset.S:1.1
--- /dev/null Sun Aug 16 06:43:44 2020
+++ src/sys/arch/x68k/stand/xxboot/memset.S Sun Aug 16 06:43:43 2020
@@ -0,0 +1,138 @@
+/* $NetBSD: memset.S,v 1.1 2020/08/16 06:43:43 isaki Exp $ */
+
+/*
+ * Copyright (C) 2020 Tetsuya Isaki. All rights reserved.
+ * Copyright (C) 2020 Y.Sugahara (moveccr). All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Size optimized (but slow) version for primary bootloader.
+ */
+
+#include <machine/asm.h>
+
+|
+| void bzero(void *dst, size_t len)
+|
+ASENTRY_NOPROFILE(bzero)
+ moveml %sp@,%d0-%d1/%a1 | %d0: (return address)
+ | %d1: dst
+ | %a1: len
+
+ subal %a0,%a0 | %a0: c = 0
+ jbra memset_common
+
+|
+| void *memset(void *dst, int c, size_t len);
+|
+ASENTRY_NOPROFILE(memset)
+ moveml %sp@,%d0-%d1/%a0-%a1 | %d0: (return address)
+ | %d1: dst
+ | %a0: c
+ | %a1: len
+memset_common:
+ addal %d1,%a1 | %a1: loop start+1 address
+
+ exg %d1,%a0 | %d1: c
+ | %a0: initial dst
+ | for return value and
+ | loop-end condition address
+ jbra 2f
+1:
+ moveb %d1,%a1@- | memset in reverse direction
+2:
+ cmpl %a1,%a0
+ jne 1b | if condition met, %a0 = dst
+ rts
+
+
+#if defined(SELFTEST)
+#include "iocscall.h"
+ .macro PRINT msg
+ leal \msg,%a1
+ IOCS(__B_PRINT)
+ .endm
+
+ .macro TEST name
+ leal \name,%a2
+ jbsr test
+ .endm
+
+ASENTRY_NOPROFILE(selftest_memset)
+ moveml %d2-%d7/%a2-%a6,%sp@-
+ PRINT %pc@(msg_testname)
+
+ TEST test1
+ TEST test2
+
+ PRINT %pc@(msg_crlf)
+ moveml %sp@+,%d2-%d7/%a2-%a6
+ rts
+
+test:
+ movel %a2@+,buf:W | initial contents of buffer
+ movel %a2@+,%sp@- | push len
+ movel %a2@+,%sp@- | push c
+ movel %a2@+,%a3 | keep dst and
+ movel %a3,%sp@- | push dst
+ jbsr memset
+ leal %sp@(12),%sp
+
+ cmpal %a3,%a0 | compare return value
+ jne fail
+ movel %a2@+,%d0 | compare buf[0..4]
+ cmpl buf:W,%d0
+ jne fail
+ PRINT %pc@(msg_ok)
+ rts
+fail:
+ PRINT %pc@(msg_fail)
+ rts
+
+test1:
+ .long 0x11223344 | initial buf
+ .long 2 | len
+ .long 0xaa | c
+ .long buf+1 | dst
+ .long 0x11aaaa44 | expected buf
+
+test2:
+ | len == 0
+ .long 0x11223344 | initial buf
+ .long 0 | len
+ .long 0x55 | c
+ .long buf+1 | dst
+ .long 0x11223344 | expected buf
+
+msg_testname:
+ .asciz "memset"
+msg_ok:
+ .asciz " ok"
+msg_fail:
+ .asciz " fail"
+msg_crlf:
+ .asciz "\r\n"
+
+ BSS(buf, 8)
+#endif
Index: src/sys/arch/x68k/stand/xxboot/fdboot_ustarfs/Makefile
diff -u /dev/null src/sys/arch/x68k/stand/xxboot/fdboot_ustarfs/Makefile:1.1
--- /dev/null Sun Aug 16 06:43:44 2020
+++ src/sys/arch/x68k/stand/xxboot/fdboot_ustarfs/Makefile Sun Aug 16 06:43:44 2020
@@ -0,0 +1,11 @@
+# $NetBSD: Makefile,v 1.1 2020/08/16 06:43:44 isaki Exp $
+
+FS= ustarfs
+BOOTCPPFLAGS+= -DXXBOOT_$(FS:tu)
+
+# ustarfs requires printf...
+BOOTSRCS+= printf.c subr_prf.c panic.c closeall.c consio1.c
+
+TOUCHPROG= @true
+
+.include "../Makefile.xxboot"