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

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:  *
        !            32:  * PATCHES MAGIC                LEVEL   PATCH THAT GOT US HERE
        !            33:  * --------------------         -----   ----------------------
        !            34:  * CURRENT PATCH LEVEL:         1       00088
        !            35:  * --------------------         -----   ----------------------
        !            36:  *
        !            37:  * 23 Oct 92   Joerg Lohse             changed ccb opcode for compatibility
        !            38:  *                                     with Adaptec AHA-1542A
1.1       root       39:  */
                     40: 
                     41: #include "param.h"
                     42: #include "disklabel.h"
                     43: #include "i386/isa/asreg.h"
                     44: 
                     45: /* RELOC should be defined with a -D flag to cc */
                     46: 
                     47: #define SECOND_LEVEL_BOOT_START (RELOC + 0x400)
                     48: #define READ_SIZE 8192
                     49: 
                     50: #define as_port 0x330
                     51: #define target 0
                     52: 
                     53: 
                     54: #define NBLOCKS (READ_SIZE / 512) /* how many logical blocks to read */
                     55: 
                     56: 
                     57: /* These are the parameters to pass to the second level boot */
                     58: #define dev 4 /* major device number of as driver in
                     59:                 i386/stand/conf.c and i386/i386/conf.c */
                     60: #define unit 0 /* partition number of root file system */
                     61: #define off 0 /* block offset of root file system */
                     62: 
                     63: /* inline i/o borrowed from Roell X server */
                     64: static __inline__ void
                     65: outb(port, val)
                     66: short port;
                     67: char val;
                     68: {
                     69:    __asm__ volatile("outb %%al, %1" : :"a" (val), "d" (port));
                     70: }
                     71: 
                     72: static __inline__ unsigned int
                     73: inb(port)
                     74: short port;
                     75: {
                     76:    unsigned int ret;
                     77:    __asm__ volatile("xorl %%eax, %%eax; inb %1, %%al"
                     78:                    : "=a" (ret) : "d" (port));
                     79:    return ret;
                     80: }
                     81: 
                     82: /* this code is linked at 0x7c00 and is loaded there by the BIOS */
                     83: 
                     84: asm ("
                     85:        /* we're running in 16 real mode, so normal assembly doesn't work */
                     86: bootbase:
                     87:        /* interrupts off */
                     88:        cli
                     89: 
                     90:        /* load gdt */
                     91:        .byte 0x2e,0x0f,0x01,0x16 /* lgdt %cs:$imm */
                     92:        .word _gdtarg + 2
                     93: 
                     94:        /* turn on protected mode */
                     95:        smsw    %ax
                     96:        orb     $1,%al
                     97:        lmsw    %ax
                     98: 
                     99:        /* flush prefetch queue and reload %cs */
                    100:        .byte 0xea /* ljmp $8, flush */
                    101:        .word flush
                    102:        .word 8
                    103: 
                    104: flush:
                    105:        /* now running in 32 bit mode */
                    106:        movl    $0x10,%eax
                    107:        movl    %ax,%ds
                    108:        movl    %ax,%es
                    109:        movl    %ax,%ss
                    110:        movl    $0x7c00,%esp
                    111:        call    _main
                    112: "); /* end of asm */
                    113: 
                    114: const char gdt[] = {
                    115:        0, 0, 0, 0, 0, 0, 0, 0,
                    116:        0xff, 0xff, 0, 0, 0, 0x9f, 0xcf, 0, /* code segment */
                    117:        0xff, 0xff, 0, 0, 0, 0x93, 0xcf, 0, /* data segment */
                    118: };
                    119: 
                    120: const struct {
                    121:        short filler;
                    122:        short size;
                    123:        const char *gdt;
                    124: } gdtarg = { 0, sizeof gdt - 1, gdt };
                    125: 
                    126: #define CRTBASE ((char *)0xb8000)
                    127: #define CHECKPOINT(x) (CRTBASE[0] = x)
                    128: 
                    129: volatile struct mailbox_entry mailbox[2];
                    130: const char ccb[] = {
1.1.1.2 ! root      131:        0, /* opcode: normal read/write */
1.1       root      132:        (target << 5) | 8, /* target num and read flag */
                    133:        10, /* scsi cmd len */
                    134:        1, /* no automatic request for sense */
                    135:        READ_SIZE >> 16, /* data length */
                    136:        READ_SIZE >> 8,
                    137:        READ_SIZE,
                    138:        RELOC >> 16, /* data pointer */
                    139:        RELOC >> 8,
                    140:        RELOC,
                    141:        0, 0, 0, /* link pointer */
                    142:        0, /* link id */
                    143:        0, /* host status */
                    144:        0, /* target status */
                    145:        0, 0, /* reserved */
                    146: 
                    147:        /* scsi cdb */
                    148:        0x28, /* read opcode */
                    149:        0, /* logical unit number */
                    150:        0, 0, 0, 0, /* logical block address */
                    151:        0,      /* reserved */
                    152:        0, NBLOCKS, /* transfer length */
                    153:        0, /* link control */
                    154: };
                    155: 
                    156: int (*f)();
                    157: 
                    158: main ()
                    159: {
                    160:        int i;
                    161:        extern char edata[], end[];
                    162:        char volatile * volatile p, *q;
                    163:        int physaddr;
                    164: 
                    165:        CHECKPOINT ('a');
                    166: 
                    167:        /* clear bss */
                    168:        for (p = edata; p < end; p++)
                    169:                *p = 0;
                    170: 
                    171:        f = (int (*)())SECOND_LEVEL_BOOT_START;
                    172: 
                    173:        /* dma setup: see page 5-31 in the Adaptech manual */
                    174:        /* this knows we are using drq 5 */
                    175:        outb (0xd6, 0xc1);
                    176:        outb (0xd4, 0x01);
                    177: 
                    178:        outb (as_port + AS_CONTROL, AS_CONTROL_SRST);
                    179: 
                    180:        /* delay a little */
                    181:        inb (0x84);
                    182:        
                    183:        while (inb (as_port + AS_STATUS) != (AS_STATUS_INIT | AS_STATUS_IDLE))
                    184:                ;
                    185: 
                    186:        CHECKPOINT ('b');
                    187: 
                    188:        as_put_byte (AS_CMD_MAILBOX_INIT);
                    189:        as_put_byte (1); /* one mailbox out, one in */
                    190:        as_put_byte ((int)mailbox >> 16);
                    191:        as_put_byte ((int)mailbox >> 8);
                    192:        as_put_byte ((int)mailbox);
                    193: 
                    194:        while (inb (as_port + AS_STATUS) & AS_STATUS_INIT)
                    195:                ;
                    196: 
                    197:        CHECKPOINT ('c');
                    198: 
                    199:        mailbox[0].msb = (int)ccb >> 16;
                    200:        mailbox[0].mid = (int)ccb >> 8;
                    201:        mailbox[0].lsb = (int)ccb;
                    202:        mailbox[0].cmd = 1;
                    203: 
                    204:        as_put_byte (AS_CMD_START_SCSI_COMMAND);
                    205: 
                    206:        /* wait for done */
                    207:        while (mailbox[1].cmd == 0)
                    208:                ;
                    209: 
                    210:        CHECKPOINT ('d');
                    211: 
                    212:        if (mailbox[1].cmd != 1) {
                    213:                /* some error */
                    214:                CHECKPOINT ('X');
                    215:                while (1);
                    216:        }
                    217: 
                    218:        CHECKPOINT ('e');
                    219: 
                    220:        /* the optimazation that gcc uses when it knows we are jumpping
                    221:         * to a constant address is broken, so we have to use a variable 
                    222:         * here
                    223:         */
                    224:        (*f)(dev, unit, off);
                    225: }
                    226: 
                    227: int
                    228: as_put_byte (val)
                    229: int val;
                    230: {
                    231:        while (inb (as_port + AS_STATUS) & AS_STATUS_CDF)
                    232:                ;
                    233:        outb (as_port + AS_DATA_OUT, val);
                    234: }
                    235: 
                    236: asm ("
                    237: ebootblkcode:
                    238:        . = 510
                    239:        .byte 0x55
                    240:        .byte 0xaa
                    241: ebootblk:                      /* MUST BE EXACTLY 0x200 BIG FOR SURE */
                    242: ");

unix.superglobalmegacorp.com

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