Annotation of coherent/d/conf/old_tboot/gift.c, revision 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.