Annotation of coherent/d/conf/tboot/gift.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * gift.c -- Prepare a gift of information for the program currently loaded.
                      3:  *
                      4:  * To pass a new data structure into the kernel:
                      5:  *
                      6:  * 1. Define your new data structure in typed.h.  You will probably want
                      7:  *    to define some supporting routines for your data structure.  These
                      8:  *    should go in a file by themselves.  Be sure to add the file to the
                      9:  *    tboot Makefile.
                     10:  * 
                     11:  * 2. Write a routine that takes at least an ffp, which will generate your
                     12:  *    data structure and write it into the ffp.  The routine should return 0
                     13:  *    if it ran out of space in the FIFO.  Other return values are permissible,
                     14:  *    but ignored.  Add arguments to prepare_gift() as needed.  It is called
                     15:  *    only from the end of execute() in execute.c.
                     16:  *
                     17:  * 3. Add a call to your routine to prepare_gift() in the section marked
                     18:  *    FILL THE BOX.  This is an if statement with || seperated calls.  The
                     19:  *    most important data structures should be called first, because later
                     20:  *    calls will be skipped if the FIFO fills.
                     21:  *
                     22:  * 4. In the kernel (probably in a driver) you will want to add a loop to
                     23:  *    look through the gift for your data structure:
                     24:  *
                     25:  *    FIFO *ffp;
                     26:  *    typed_space *tp;
                     27:  *
                     28:  *    ffp = fifo_open(&boot_gift, 0);  -- Open gift for reading. 
                     29:  * 
                     30:  *    if (F_NULL == ffp) {
                     31:  *       indicate_error("Could not open boot_gift.");
                     32:  *    } else {
                     33:  *        while (T_NULL != (tp = fifo_read(ffp))) {    -- While not EOFIFO.
                     34:  *           if (T_MYTYPE == tp->ts_type) {    -- Is this my type?
                     35:  *               my_handler(tp->ts_data);      -- Process the data.
                     36:  *           }
                     37:  *        }
                     38:  *    }
                     39:  *
                     40:  *    Be sure to include fifo.c and typed.h into your kernel.
                     41:  *       
                     42:  */
                     43: #include <string.h>
                     44: #include <sys/fdisk.h>
                     45: #include <sys/typed.h>
                     46: #include "tboot.h"
                     47: 
                     48: 
                     49: #define GIFTBOX        4096 /* Size of the gift box (maximum size of gift.)  */
                     50: 
                     51: 
                     52: /* We have to build the gift in the local segment and then copy it in
                     53:  * place.  In a better world, the gift could be built in place.
                     54:  */
                     55: TYPED_SPACE(local_gift, GIFTBOX, T_FIFO_SIC); /* Static In-Core Fifo.  */
                     56: 
                     57: 
                     58: /* Prepare a gift of information for the program currently loaded.
                     59:  *
                     60:  * The gift is a Static In-Core FIFO whose objects are typed spaces.
                     61:  *
                     62:  * argv is the command vector needed by gift_argf().
                     63:  *
                     64:  * It should be placed in memory at data_seg:offset.
                     65:  */
                     66: void
                     67: prepare_gift(data_seg, offset, argv)
                     68:        uint16 data_seg;
                     69:        uint16 offset;
                     70:        char *argv[];
                     71: {
                     72:        FIFO *ffp;              /* Fifo pointer for a handle.  */
                     73:        typed_space gift_header;        /* Header for destination box.  */
                     74:        char buff[sizeof("65536")];     /* For outputting base 10 integers.  */
                     75: 
                     76:        /* Value of ds register, initialized in Startup.s.  */
                     77:        extern uint16 myds;
                     78: 
                     79:        /* Find out how big a gift we may offer.  */
                     80:        ffcopy(&gift_header, myds, offset, data_seg, sizeof(typed_space));
                     81:        if (gift_header.ts_size > local_gift.ts_size) {
                     82:                puts("WARNING: argument structures larger than ");
                     83:                itobase((int) local_gift.ts_size, buff, 10);
                     84:                puts(buff);
                     85:                puts(" bytes are not currently supported.\r\n");
                     86:                puts("Truncating down from ");
                     87:                itobase((int) gift_header.ts_size, buff, 10);
                     88:                puts(buff);
                     89:                puts(".\r\n");
                     90:                puts("This is probably harmless.\r\n");
                     91:        } else {
                     92:                /* Requested gift is smaller than what we can offer.  */
                     93:                local_gift.ts_size = gift_header.ts_size;
                     94:        }
                     95: 
                     96:        /* ASSERTION: local_gift is now no larger than boot_gift.  */
                     97: 
                     98:        /* Open the local gift box.  */
                     99:        if (F_NULL == (ffp = fifo_open(&local_gift, 1))) {
                    100:                puts("prepare_gift():  Can't open local_gift for writing.\r\n");
                    101:                puts("prepare_gift():  No information will be passed.\r\n");
                    102:                return;
                    103:        }
                    104: 
                    105:        /* FILL THE BOX.  */
                    106:        /* Stop filling in if we run out of space.  */
                    107:        if ((0 == gift_drive_params(ffp)) ||
                    108:            (0 == gift_rootdev(ffp)) ||
                    109:            (0 == gift_argf(ffp, argv))
                    110:           ) {
                    111:                puts("prepare_gift(): WARNING: not enough room for all arguments.\r\n");
                    112:                puts("Only ");
                    113:                itobase((int) ((char *)ffp->f_offset - (char *)ffp->f_space), buff, 10);
                    114:                puts(buff);
                    115:                puts(" bytes submitted.\r\n");
                    116:        }
                    117: 
                    118:        fifo_close(ffp);
                    119: 
                    120:        /* Copy the gift into the loaded program.  */
                    121:        ffcopy(offset, data_seg, &local_gift, myds,
                    122:                (uint16) local_gift.ts_size);
                    123: } /* prepare_gift() */
                    124: 
                    125: 
                    126: /* Load the BIOS parameters loaded up by the startup code.  */
                    127: int
                    128: gift_drive_params(ffp)
                    129:        FIFO *ffp;
                    130: {
                    131:        int i;
                    132:        int num_of_drives;
                    133:        struct reg r;
                    134:        BIOS_DISK diskparms;
                    135:        
                    136:        
                    137:        num_of_drives = get_num_of_drives();
                    138: 
                    139:        if (verbose_flag) {
                    140:                puts("Found 0x");
                    141:                print16(num_of_drives);
                    142:                puts(" drives.\r\n");
                    143:        }
                    144: 
                    145:        for (i = 0; i < num_of_drives; ++i) {
                    146:         
                    147:                r.r_ax = DISK_PARAMS;
                    148:                r.r_dx = HARD_DRIVE + i;
                    149:        
                    150:                intcall(&r, &r, DISKINT);       /* Ask the BIOS.  */
                    151: 
                    152:                diskparms.dp_drive = i;
                    153: 
                    154:                /* ch is the lower 8 bits of number of cylinders.
                    155:                 * The high two bits of cl are the top two bits of
                    156:                 * 10 bit number of cylinders.
                    157:                 *
                    158:                 * The cylinder count is actually 1 short.
                    159:                 */
                    160:                diskparms.dp_cylinders = (uint16) (
                    161:                          ((LOW(r.r_cx) >> 6) * 256) + /* Top two bits...  */
                    162:                          (HIGH(r.r_cx) + 1)
                    163:                        );
                    164: 
                    165:        
                    166:                /* The head count is actually 1 short.  */
                    167: 
                    168:                diskparms.dp_heads = ((uint16) HIGH(r.r_dx)) + 1;
                    169:        
                    170:                /* Only the lower 6 bits of cl are the sectors per track.  */
                    171:                
                    172:                diskparms.dp_sectors = (uint16) (SIXBITS & LOW(r.r_cx));
                    173: 
                    174:                /* Store these parameters for delivery.  */
                    175:                if (T_NULL == fifo_write_untyped(ffp,
                    176:                                                 &diskparms,
                    177:                                                 (int32) sizeof(BIOS_DISK),
                    178:                                                 T_BIOS_DISK)
                    179:                   ) {
                    180:                        puts("gift_drive_params() ran out of space.");
                    181:                        return(0);
                    182:                }
                    183: 
                    184:        } /* for i = 0 to num_of_drives - 1 */
                    185: 
                    186:        return(1);      /* We didn't run out of space.  */
                    187: 
                    188: } /* gift_drive_params() */
                    189: 
                    190: /*
                    191:  * We'd really rather have a dynamic in-core fifo, but they are not
                    192:  * yet implimented.  We'll have to settle for a fixed length argument list.
                    193:  */
                    194: TYPED_SPACE(argf, BLOCK, T_FIFO_SIC);
                    195: 
                    196: /*
                    197:  * To read this item from bootgift, use the procedure outlined above in
                    198:  * point 4 to find the entry marked T_STR_ARGF.  You must then explicitly
                    199:  * recast it with RETYPE(tp->ts_data, T_FIFO_SIC).  Then you can open it
                    200:  * as a FIFO, with code modeled on point 4 above.  This scheme seemed
                    201:  * the simplest for uniquely identifying the argument FIFO.
                    202:  * Each element of the FIFO is a T_STR_STR, so ts_data for these is
                    203:  * just a NUL terminated string.
                    204:  */
                    205: 
                    206: /*
                    207:  * Write an argument fifo into ffp from the argument vector argv[].
                    208:  * Returns 0 if it runs out of space, 1 on success, 2 if it could not
                    209:  * open the local gift box for some reason.
                    210:  */
                    211: int
                    212: gift_argf(ffp, argv)
                    213:        FIFO *ffp;
                    214:        char *argv[];
                    215: {
                    216:        FIFO *argfp;    /* For the argument fifo we're going to build.  */
                    217:        char *current_token;
                    218:        int i;
                    219: 
                    220:        /* Open the local gift box.  */
                    221:        if (F_NULL == (argfp = fifo_open(&argf, 1))) {
                    222:                puts("gift_argf():  Can't open local argument fifo for writing.\r\n");
                    223:                puts("gift_argf():  No command line information will be passed.\r\n");
                    224:                return(2);
                    225:        }
                    226: 
                    227:        current_token = argv[0];
                    228:        /*
                    229:         * Build the command fifo.
                    230:         */
                    231:        for (i = 0; NULL != current_token; current_token = argv[++i]) {
                    232:                if (T_NULL == 
                    233:                        fifo_write_untyped(argfp,
                    234:                                   current_token,
                    235:                                   (int32) (strlen(current_token) + 1),
                    236:                                   T_STR_STR)
                    237:                ) {
                    238:                        puts("gift_argf():  WARNING:  Command line too long.\r\n");
                    239:                        puts("Truncating.\r\n");
                    240:                        break;
                    241:                }
                    242:        }
                    243: 
                    244: 
                    245:        /*
                    246:         * Truncate argf to the minimum size needed.
                    247:         */
                    248:        RESIZE(&argf, fifo_len(argfp));
                    249: 
                    250:        /*
                    251:         * Now that we've filled the FIFO, let's mark
                    252:         * it as an argument fifo.
                    253:         */
                    254:        RETYPE(&argf, T_STR_ARGF);
                    255: 
                    256:        close(argfp);
                    257: 
                    258:        /* Write it into ffp.  */
                    259:        if (T_NULL == fifo_write(ffp, &argf)) {
                    260:                puts("gift_argf() ran out of space.");
                    261:                return(0);
                    262:        }
                    263: 
                    264:        return(1);
                    265: } /* gift_argf() */
                    266: 
                    267: /*
                    268:  * Write a structure describing the boot partition into a fifo.
                    269:  * Returns 1 on success, 0 if it runs out of space, or 2 if it
                    270:  * can't read the boot block.
                    271:  */
                    272: int
                    273: gift_rootdev(ffp)
                    274:        FIFO *ffp;
                    275: {
                    276: #define        NOPARTITION     255     /* Convenient illegal partition number.  */
                    277: #define PART_PER_DRIVE 4       /* Number of partitions per drive.  */
                    278: 
                    279:        BIOS_ROOTDEV myrootdev; /* Build the data to be passed here.  */
                    280:        FDISK_S fp[NPARTN];     /* Room for a partition table from disk.  */
                    281:        int8 i;
                    282: 
                    283:        extern uint8 drive;     /* Drive number from secondary boot.  */
                    284:        extern uint32 first;    /* Block number of start of partition.  */
                    285:        
                    286:        /* Fetch the partition table from disk.  */
                    287:        if (0 == fdisk(fp)) {
                    288:                puts("gift_rootdev() WARNING: invalid boot block.\r\n");
                    289:                return(2);
                    290:        }
                    291: 
                    292:        /* Mark an invalid partition.  */
                    293:        myrootdev.rd_partition = NOPARTITION;
                    294: 
                    295:        /* Look for the current partition in the table.  */
                    296:        for (i=0; i < NPARTN; ++i) {
                    297:                if (first == fp[i].p_base) {
                    298:                        myrootdev.rd_partition = i;
                    299:                        break;
                    300:                }
                    301:        }
                    302: 
                    303:        if (NOPARTITION == myrootdev.rd_partition) {
                    304:                puts("gift_rootdev() WARNING: Can't find my partition.\r\n");
                    305:                return(2);
                    306:        }
                    307: 
                    308:        /* Adjust the partition for the drive number.  */
                    309:        myrootdev.rd_partition += (PART_PER_DRIVE * drive);
                    310: 
                    311:        if (T_NULL == fifo_write_untyped(ffp,
                    312:                                         &myrootdev,
                    313:                                         (int32) sizeof(BIOS_ROOTDEV),
                    314:                                         T_BIOS_ROOTDEV)
                    315:        ) {
                    316:                puts("Ran out of space in gift_rootdev().\r\n");
                    317:                return(0);
                    318:        } else {
                    319:                return(1);
                    320:        }
                    321: } /* gift_rootdev() */
                    322: 
                    323: /* Dump the contents of boot_gift.  */
                    324: void
                    325: dump_gift()
                    326: {
                    327:        extern typed_space boot_gift;
                    328: 
                    329:        puts("Dumping boot_gift.\r\n");
                    330:        dump_fifo(&boot_gift);
                    331: }
                    332: 
                    333: /* Dump the contents of a fifo.  */
                    334: void
                    335: dump_fifo(fifo)
                    336:        typed_space *fifo;
                    337: {
                    338:     FIFO *ffp;
                    339:     typed_space *tp;
                    340: 
                    341:     puts("Dumping a fifo.\r\n");
                    342: 
                    343:     if (F_NULL == (ffp = fifo_open(fifo, 0))) {        /* Open gift for reading.  */
                    344:        puts("Can't open fifo.\r\n");
                    345:        return;
                    346:     }
                    347: 
                    348:     while (T_NULL != (tp = fifo_read(ffp))) {  /* While not EOFIFO.  */
                    349:        switch(tp->ts_type) {
                    350:        case T_BIOS_DISK:
                    351:                dump_bios_disk(tp->ts_data);
                    352:                break;
                    353:        case T_BIOS_ROOTDEV:
                    354:                dump_rootdev(tp->ts_data);
                    355:                break;
                    356:        case T_FIFO_SIC:
                    357:                dump_fifo(tp);
                    358:                break;
                    359:        case T_STR_STR:
                    360:                puts("String: ");
                    361:                puts(tp->ts_data);
                    362:                break;
                    363:        case T_STR_ARGF:
                    364:                RETYPE(tp, T_FIFO_SIC);
                    365:                dump_fifo(tp);
                    366:                break;
                    367:        default:
                    368:                puts("Unknown type: 0x");
                    369:                print16(tp->ts_type);
                    370:                break;
                    371:        }
                    372:        puts("\r\n");
                    373:     }
                    374:     puts("Nothing more to dump in this fifo.\r\n");
                    375: 
                    376: } /* dump_gift() */
                    377: 
                    378: /* Dump a T_BIOS_DISK typed_space.  */
                    379: void
                    380: dump_bios_disk(a_disk)
                    381:        BIOS_DISK *a_disk;
                    382: {
                    383:        char buffer[BLOCK];
                    384: 
                    385:        puts("Dumping a BIOS_DISK struct.\r\n");
                    386: 
                    387:        puts("Drive ");
                    388:        itobase((uint16) a_disk->dp_drive, buffer, 10);
                    389:        puts(buffer);
                    390: 
                    391:        puts(":  Cylinders=");
                    392:        itobase((uint16) a_disk->dp_cylinders, buffer, 10);
                    393:        puts(buffer);
                    394: 
                    395:        puts("  Heads=");
                    396:        itobase((uint16) a_disk->dp_heads, buffer, 10);
                    397:        puts(buffer);
                    398: 
                    399:        puts("  Sectors per track=");
                    400:        itobase((uint16) a_disk->dp_sectors, buffer, 10);
                    401:        puts(buffer);
                    402: 
                    403:        puts("\r\n");
                    404: } /* dump_bios_disk() */
                    405: 
                    406: 
                    407: /* Dump a T_BIOS_ROOTDEV typed_space.  */
                    408: void
                    409: dump_rootdev(a_rootdev)
                    410:        BIOS_ROOTDEV *a_rootdev;
                    411: {
                    412:        puts("Dumping a BIOS_ROOTDEV struct.\r\n");
                    413: 
                    414:        puts("partition: 0x");
                    415:        print8(a_rootdev->rd_partition);
                    416:        puts("\r\n");
                    417: } /* dump_rootdev() */

unix.superglobalmegacorp.com

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