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

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

unix.superglobalmegacorp.com

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