X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=blobdiff_plain;f=palacios%2Fsrc%2Fdevices%2Fcdrom.c;fp=palacios%2Fsrc%2Fdevices%2Fcdrom.c;h=ff1c55c1960c7f811f609470c362d9634937bad2;hp=0000000000000000000000000000000000000000;hb=ddc16b0737cf58f7aa90a69c6652cdf4090aec51;hpb=626595465a2c6987606a6bc697df65130ad8c2d3 diff --git a/palacios/src/devices/cdrom.c b/palacios/src/devices/cdrom.c new file mode 100644 index 0000000..ff1c55c --- /dev/null +++ b/palacios/src/devices/cdrom.c @@ -0,0 +1,182 @@ +/* + * This file is part of the Palacios Virtual Machine Monitor developed + * by the V3VEE Project with funding from the United States National + * Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. You can find out more at + * http://www.v3vee.org + * + * Copyright (c) 2008, Zheng Cui + * Copyright (c) 2008, Jack Lange + * Copyright (c) 2008, The V3VEE Project + * All rights reserved. + * + * Author: Zheng Cui + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + + + +#include +#include +#include + +#ifndef DEBUG_RAMDISK +#undef PrintDebug +#define PrintDebug(fmt, args...) +#endif + + + +struct cdrom_state { + uchar_t * image_addr; //memory address + ulong_t capacity_in_bytes; + ulong_t head; //current position + + struct vm_device * ide_dev; + + uchar_t lba; +}; + + + + +/* + * Load CD-ROM. Returns false if CD is not ready. + */ + +static rd_bool cdrom_insert(void * private_data) { + PrintDebug("[cdrom_insert]\n"); + return 1; +} + +/* + * Logically eject the CD. + */ +static void cdrom_eject(void * private_data) { + PrintDebug("[cdrom_eject]\n"); + return; +} + +/* + * Read CD TOC. Returns false if start track is out of bounds. + */ +static rd_bool cdrom_read_toc(void * private_data, uint8_t* buf, int* length, rd_bool msf, int start_track) +{ + *length = 4; + PrintDebug("[cdrom_read_toc]\n"); + return 1; +} + +/* + * Return CD-ROM capacity (in 2048 byte frames) + */ +static uint32_t cdrom_capacity(void * private_data) { + struct cdrom_state * cdrom = (struct cdrom_state *)private_data; + + PrintDebug("[cdrom_capacity] s_ramdiskSize = %d\n", cdrom->capacity_in_bytes); + + if (cdrom->lba) { + if (cdrom->capacity_in_bytes % 2048) { + PrintDebug("\t\t capacity in LBA is %d\n", (cdrom->capacity_in_bytes / 2048) + 1); + return (cdrom->capacity_in_bytes / 2048) + 1; + } else { + PrintDebug("\t\t capacity in LBA is %d\n", cdrom->capacity_in_bytes / 2048); + return cdrom->capacity_in_bytes / 2048; + } + } else { + PrintError("Unsupported CDROM mode in capacity query\n"); + //FIXME CHS mode + return 0; + } +} + +/* + * Read a single block from the CD + */ +static void cdrom_read_block(void * private_data, uint8_t * buf, int lba)/* __attribute__(regparm(2)); */ { + struct cdrom_state * cdrom = (struct cdrom_state *)private_data; + + V3_ASSERT(lba != 0); + + PrintDebug("[cdrom_read_block] lba = %d (cdrom_image_start=%x)\n", lba, cdrom->image_addr); + memcpy(buf, (uchar_t *)(cdrom->image_addr + lba * 2048), 2048); + //PrintDebug("Returning from read block\n"); + return; +} + +static void set_LBA(void * private_data, uchar_t lba) { + struct cdrom_state * cdrom = (struct cdrom_state *)private_data; + cdrom->lba = lba; +} + + +/* + * Start (spin up) the CD. + */ +static int cdrom_start(void * private_data) { + PrintDebug("[cdrom_start]\n"); + return 1; +} + + +static struct cdrom_ops cd_ops = { + .insert_cdrom = cdrom_insert, + .eject_cdrom = cdrom_eject, + .read_toc = cdrom_read_toc, + .capacity = cdrom_capacity, + .read_block = cdrom_read_block, + .start_cdrom = cdrom_start, + .set_LBA = set_LBA, +}; + + + + +static int cdrom_device_init(struct vm_device * dev) { + struct cdrom_state * cdrom = (struct cdrom_state *)dev->private_data; + PrintDebug("[cdrom_init]\n"); + PrintDebug("CDIMAGE located at: %x\n", cdrom->image_addr); + + //FIXME:lba + cdrom->lba = 1; + + v3_ramdisk_register_cdrom(cdrom->ide_dev, 1, 0, &cd_ops, cdrom); + + return 0; +} + + +static int cdrom_device_deinit(struct vm_device * dev) { + return 0; +} + +static struct vm_device_ops dev_ops = { + .init = cdrom_device_init, + .deinit = cdrom_device_deinit, + .reset = NULL, + .start = NULL, + .stop = NULL, +}; + +struct vm_device * v3_create_cdrom(struct vm_device * ramdisk_dev, void * ramdisk, uint_t ramdisk_size){ + struct cdrom_state * cd = (struct cdrom_state *)V3_Malloc(sizeof(struct cdrom_state)); + V3_ASSERT(cd != NULL); + + memset(cd, 0, sizeof(struct cdrom_state)); + + cd->image_addr = (uchar_t *)V3_VAddr(ramdisk); + cd->capacity_in_bytes = ramdisk_size; + cd->ide_dev = ramdisk_dev; + + PrintDebug("Creating RamDISK CDROM\n"); + + struct vm_device * cd_dev = v3_create_device("Ram Based CD", &dev_ops, cd); + + return cd_dev; +} + +