1 // Code for emulating a drive via high-memory accesses.
3 // Copyright (C) 2009 Kevin O'Connor <kevin@koconnor.net>
5 // This file may be distributed under the terms of the GNU LGPLv3 license.
7 #include "disk.h" // process_ramdisk_op
8 #include "util.h" // dprintf
9 #include "memmap.h" // add_e820
10 #include "biosvar.h" // GET_GLOBAL
11 #include "bregs.h" // struct bregs
13 #define RAMDISK_SECTOR_SIZE 512
18 if (!CONFIG_COREBOOT_FLASH || !CONFIG_FLASH_FLOPPY)
22 struct cbfs_file *file = cbfs_findprefix("floppyimg/", NULL);
25 u32 size = cbfs_datasize(file);
26 dprintf(3, "Found floppy file %s of size %d\n", cbfs_filename(file), size);
27 int ftype = find_floppy_type(size);
29 dprintf(3, "No floppy type found for ramdisk size\n");
33 // Allocate ram for image.
34 struct e820entry *e = find_high_area(size);
36 dprintf(3, "No ram for ramdisk\n");
39 u32 loc = e->start + e->size - size;
40 add_e820(loc, size, E820_RESERVED);
42 // Copy image into ram.
43 cbfs_copyfile(file, (void*)loc, size);
46 dprintf(1, "Mapping CBFS floppy %s to addr %x\n", cbfs_filename(file), loc);
47 addFloppy(loc, ftype, DTYPE_RAMDISK);
51 ramdisk_op(struct disk_op_s *op, int iswrite)
53 u32 offset = GET_GLOBAL(Drives.drives[op->driveid].cntl_id);
54 offset += (u32)op->lba * RAMDISK_SECTOR_SIZE;
55 u64 opd = GDT_DATA | GDT_LIMIT(0xfffff) | GDT_BASE((u32)op->buf_fl);
56 u64 ramd = GDT_DATA | GDT_LIMIT(0xfffff) | GDT_BASE(offset);
67 // Call 0x1587 to copy data.
69 memset(&br, 0, sizeof(br));
73 br.cx = op->count * RAMDISK_SECTOR_SIZE / 2;
74 call16_int(0x15, &br);
76 return DISK_RET_SUCCESS;
80 process_ramdisk_op(struct disk_op_s *op)
82 if (!CONFIG_COREBOOT_FLASH || !CONFIG_FLASH_FLOPPY)
85 switch (op->command) {
87 return ramdisk_op(op, 0);
89 return ramdisk_op(op, 1);
93 return DISK_RET_SUCCESS;
96 return DISK_RET_EPARAM;