Annotation of Net2/arch/i386/stand/asbootblk.c, revision 1.1.1.3

1.1       root        1: /*
                      2:  * sys/i386/stand/asbootblk.c
                      3:  *
                      4:  * Boot block for Adaptech 1542 SCSI
                      5:  *
                      6:  * April 10, 1992
                      7:  * Pace Willisson
                      8:  * [email protected]
                      9:  *
                     10:  * Placed in the public domain with NO WARRANTIES, not even the
                     11:  * implied warranties for MERCHANTABILITY or FITNESS FOR A 
                     12:  * PARTICULAR PURPOSE.
                     13:  *
                     14:  * To compile:
                     15:  *
                     16:  *     cc -O -c -DRELOC=0x70000 asbootblk.c
                     17:  *     ld -N -T 7c00 asbootblk.o
                     18:  *
                     19:  * This should result in a file with 512 bytes of text and no initialized 
                     20:  * data.  Strip the 32 bit header and place in block 0.
                     21:  *
                     22:  * When run, this program copies at least the first 8 blocks of SCSI
                     23:  * target 0 to the address specified by RELOC, then jumps to the
                     24:  * address RELOC+1024 (skipping the boot block and disk label).  Usually,
                     25:  * disks have 512 bytes per block, but I don't think they ever have
                     26:  * less, and it wont hurt if they are bigger, as long as RELOC + 8*SIZE
                     27:  * is less than 0xa0000.
                     28:  *
                     29:  * This bootblock does not support fdisk partitions, and can only be used
                     30:  * as the master boot block.
1.1.1.2   root       31:  *
1.1.1.3 ! root       32:  *     asbootblk.c,v 1.3 1993/05/22 08:02:07 cgd Exp
1.1       root       33:  */
                     34: 
                     35: #include "param.h"
                     36: #include "disklabel.h"
                     37: #include "i386/isa/asreg.h"
                     38: 
                     39: /* RELOC should be defined with a -D flag to cc */
                     40: 
                     41: #define SECOND_LEVEL_BOOT_START (RELOC + 0x400)
                     42: #define READ_SIZE 8192
                     43: 
                     44: #define as_port 0x330
                     45: #define target 0
                     46: 
                     47: 
                     48: #define NBLOCKS (READ_SIZE / 512) /* how many logical blocks to read */
                     49: 
                     50: 
                     51: /* These are the parameters to pass to the second level boot */
                     52: #define dev 4 /* major device number of as driver in
                     53:                 i386/stand/conf.c and i386/i386/conf.c */
                     54: #define unit 0 /* partition number of root file system */
                     55: #define off 0 /* block offset of root file system */
                     56: 
                     57: /* inline i/o borrowed from Roell X server */
                     58: static __inline__ void
                     59: outb(port, val)
                     60: short port;
                     61: char val;
                     62: {
                     63:    __asm__ volatile("outb %%al, %1" : :"a" (val), "d" (port));
                     64: }
                     65: 
                     66: static __inline__ unsigned int
                     67: inb(port)
                     68: short port;
                     69: {
                     70:    unsigned int ret;
                     71:    __asm__ volatile("xorl %%eax, %%eax; inb %1, %%al"
                     72:                    : "=a" (ret) : "d" (port));
                     73:    return ret;
                     74: }
                     75: 
                     76: /* this code is linked at 0x7c00 and is loaded there by the BIOS */
                     77: 
                     78: asm ("
                     79:        /* we're running in 16 real mode, so normal assembly doesn't work */
                     80: bootbase:
                     81:        /* interrupts off */
                     82:        cli
                     83: 
                     84:        /* load gdt */
                     85:        .byte 0x2e,0x0f,0x01,0x16 /* lgdt %cs:$imm */
                     86:        .word _gdtarg + 2
                     87: 
                     88:        /* turn on protected mode */
                     89:        smsw    %ax
                     90:        orb     $1,%al
                     91:        lmsw    %ax
                     92: 
                     93:        /* flush prefetch queue and reload %cs */
                     94:        .byte 0xea /* ljmp $8, flush */
                     95:        .word flush
                     96:        .word 8
                     97: 
                     98: flush:
                     99:        /* now running in 32 bit mode */
                    100:        movl    $0x10,%eax
                    101:        movl    %ax,%ds
                    102:        movl    %ax,%es
                    103:        movl    %ax,%ss
                    104:        movl    $0x7c00,%esp
                    105:        call    _main
                    106: "); /* end of asm */
                    107: 
                    108: const char gdt[] = {
                    109:        0, 0, 0, 0, 0, 0, 0, 0,
                    110:        0xff, 0xff, 0, 0, 0, 0x9f, 0xcf, 0, /* code segment */
                    111:        0xff, 0xff, 0, 0, 0, 0x93, 0xcf, 0, /* data segment */
                    112: };
                    113: 
                    114: const struct {
                    115:        short filler;
                    116:        short size;
                    117:        const char *gdt;
                    118: } gdtarg = { 0, sizeof gdt - 1, gdt };
                    119: 
                    120: #define CRTBASE ((char *)0xb8000)
                    121: #define CHECKPOINT(x) (CRTBASE[0] = x)
                    122: 
                    123: volatile struct mailbox_entry mailbox[2];
                    124: const char ccb[] = {
1.1.1.2   root      125:        0, /* opcode: normal read/write */
1.1       root      126:        (target << 5) | 8, /* target num and read flag */
                    127:        10, /* scsi cmd len */
                    128:        1, /* no automatic request for sense */
                    129:        READ_SIZE >> 16, /* data length */
                    130:        READ_SIZE >> 8,
                    131:        READ_SIZE,
                    132:        RELOC >> 16, /* data pointer */
                    133:        RELOC >> 8,
                    134:        RELOC,
                    135:        0, 0, 0, /* link pointer */
                    136:        0, /* link id */
                    137:        0, /* host status */
                    138:        0, /* target status */
                    139:        0, 0, /* reserved */
                    140: 
                    141:        /* scsi cdb */
                    142:        0x28, /* read opcode */
                    143:        0, /* logical unit number */
                    144:        0, 0, 0, 0, /* logical block address */
                    145:        0,      /* reserved */
                    146:        0, NBLOCKS, /* transfer length */
                    147:        0, /* link control */
                    148: };
                    149: 
                    150: int (*f)();
                    151: 
                    152: main ()
                    153: {
                    154:        int i;
                    155:        extern char edata[], end[];
                    156:        char volatile * volatile p, *q;
                    157:        int physaddr;
                    158: 
                    159:        CHECKPOINT ('a');
                    160: 
                    161:        /* clear bss */
                    162:        for (p = edata; p < end; p++)
                    163:                *p = 0;
                    164: 
                    165:        f = (int (*)())SECOND_LEVEL_BOOT_START;
                    166: 
                    167:        /* dma setup: see page 5-31 in the Adaptech manual */
                    168:        /* this knows we are using drq 5 */
                    169:        outb (0xd6, 0xc1);
                    170:        outb (0xd4, 0x01);
                    171: 
                    172:        outb (as_port + AS_CONTROL, AS_CONTROL_SRST);
                    173: 
                    174:        /* delay a little */
                    175:        inb (0x84);
                    176:        
                    177:        while (inb (as_port + AS_STATUS) != (AS_STATUS_INIT | AS_STATUS_IDLE))
                    178:                ;
                    179: 
                    180:        CHECKPOINT ('b');
                    181: 
                    182:        as_put_byte (AS_CMD_MAILBOX_INIT);
                    183:        as_put_byte (1); /* one mailbox out, one in */
                    184:        as_put_byte ((int)mailbox >> 16);
                    185:        as_put_byte ((int)mailbox >> 8);
                    186:        as_put_byte ((int)mailbox);
                    187: 
                    188:        while (inb (as_port + AS_STATUS) & AS_STATUS_INIT)
                    189:                ;
                    190: 
                    191:        CHECKPOINT ('c');
                    192: 
                    193:        mailbox[0].msb = (int)ccb >> 16;
                    194:        mailbox[0].mid = (int)ccb >> 8;
                    195:        mailbox[0].lsb = (int)ccb;
                    196:        mailbox[0].cmd = 1;
                    197: 
                    198:        as_put_byte (AS_CMD_START_SCSI_COMMAND);
                    199: 
                    200:        /* wait for done */
                    201:        while (mailbox[1].cmd == 0)
                    202:                ;
                    203: 
                    204:        CHECKPOINT ('d');
                    205: 
                    206:        if (mailbox[1].cmd != 1) {
                    207:                /* some error */
                    208:                CHECKPOINT ('X');
                    209:                while (1);
                    210:        }
                    211: 
                    212:        CHECKPOINT ('e');
                    213: 
                    214:        /* the optimazation that gcc uses when it knows we are jumpping
                    215:         * to a constant address is broken, so we have to use a variable 
                    216:         * here
                    217:         */
                    218:        (*f)(dev, unit, off);
                    219: }
                    220: 
                    221: int
                    222: as_put_byte (val)
                    223: int val;
                    224: {
                    225:        while (inb (as_port + AS_STATUS) & AS_STATUS_CDF)
                    226:                ;
                    227:        outb (as_port + AS_DATA_OUT, val);
                    228: }
                    229: 
                    230: asm ("
                    231: ebootblkcode:
                    232:        . = 510
                    233:        .byte 0x55
                    234:        .byte 0xaa
                    235: ebootblk:                      /* MUST BE EXACTLY 0x200 BIG FOR SURE */
                    236: ");

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.