2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
11 * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Jack Lange <jarusl@cs.northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20 #include <palacios/vmm.h>
21 #include <devices/ram_cd.h>
22 #include <palacios/vmm_dev_mgr.h>
23 #include <devices/ide.h>
25 #ifndef CONFIG_DEBUG_IDE
27 #define PrintDebug(fmt, args...)
33 uint32_t capacity; // in bytes
35 struct vm_device * ide;
42 // CDs always read 2048 byte blocks... ?
43 static int cd_read(uint8_t * buf, int block_count, uint64_t lba, void * private_data) {
44 struct vm_device * cd_dev = (struct vm_device *)private_data;
45 struct cd_state * cd = (struct cd_state *)(cd_dev->private_data);
46 int offset = lba * ATAPI_BLOCK_SIZE;
47 int length = block_count * ATAPI_BLOCK_SIZE;
49 PrintDebug("Reading RAM CD at (LBA=%d) offset %d (length=%d)\n", (uint32_t)lba, offset, length);
51 memcpy(buf, (uint8_t *)(cd->disk_image + offset), length);
57 static uint32_t cd_get_capacity(void * private_data) {
58 struct vm_device * cd_dev = (struct vm_device *)private_data;
59 struct cd_state * cd = (struct cd_state *)(cd_dev->private_data);
60 PrintDebug("Querying RAM CD capacity (bytes=%d) (ret = %d)\n",
61 cd->capacity, cd->capacity / ATAPI_BLOCK_SIZE);
62 return cd->capacity / ATAPI_BLOCK_SIZE;
65 static struct v3_cd_ops cd_ops = {
67 .get_capacity = cd_get_capacity,
73 static int cd_free(struct vm_device * dev) {
77 static struct v3_device_ops dev_ops = {
85 static int cd_init(struct guest_info * vm, void * cfg_data) {
86 struct cd_state * cd = NULL;
87 struct ram_cd_cfg * cfg = (struct ram_cd_cfg *)cfg_data;
89 if (cfg->size % ATAPI_BLOCK_SIZE) {
90 PrintError("CD image must be an integral of block size (ATAPI_BLOCK_SIZE=%d)\n", ATAPI_BLOCK_SIZE);
94 cd = (struct cd_state *)V3_Malloc(sizeof(struct cd_state));
96 PrintDebug("Registering Ram CD at %p (size=%d)\n", (void *)cfg->ramdisk, cfg->size);
99 cd->disk_image = cfg->ramdisk;
100 cd->capacity = cfg->size;
102 cd->ide = v3_find_dev(vm, cfg->ide);
105 PrintError("Could not find backend %s\n", cfg->ide);
110 cd->drive = cfg->drive;
112 struct vm_device * dev = v3_allocate_device("RAM-CD", &dev_ops, cd);
114 if (v3_attach_device(vm, dev) == -1) {
115 PrintError("Could not attach device %s\n", "RAM-CD");
120 if (v3_ide_register_cdrom(cd->ide, cd->bus, cd->drive, "RAM-CD", &cd_ops, dev) == -1) {
128 device_register("RAM-CD", cd_init)