Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


imported SEABIOS source tree
[palacios.git] / bios / seabios / src / ramdisk.c
1 // Code for emulating a drive via high-memory accesses.
2 //
3 // Copyright (C) 2009  Kevin O'Connor <kevin@koconnor.net>
4 //
5 // This file may be distributed under the terms of the GNU LGPLv3 license.
6
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
12 #include "boot.h" // boot_add_floppy
13
14 void
15 ramdisk_setup(void)
16 {
17     if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH || !CONFIG_FLASH_FLOPPY)
18         return;
19
20     // Find image.
21     struct cbfs_file *file = cbfs_findprefix("floppyimg/", NULL);
22     if (!file)
23         return;
24     const char *filename = cbfs_filename(file);
25     u32 size = cbfs_datasize(file);
26     dprintf(3, "Found floppy file %s of size %d\n", filename, size);
27     int ftype = find_floppy_type(size);
28     if (ftype < 0) {
29         dprintf(3, "No floppy type found for ramdisk size\n");
30         return;
31     }
32
33     // Allocate ram for image.
34     void *pos = memalign_tmphigh(PAGE_SIZE, size);
35     if (!pos) {
36         warn_noalloc();
37         return;
38     }
39     add_e820((u32)pos, size, E820_RESERVED);
40
41     // Copy image into ram.
42     cbfs_copyfile(file, pos, size);
43
44     // Setup driver.
45     struct drive_s *drive_g = init_floppy((u32)pos, ftype);
46     if (!drive_g)
47         return;
48     drive_g->type = DTYPE_RAMDISK;
49     dprintf(1, "Mapping CBFS floppy %s to addr %p\n", filename, pos);
50     char *desc = znprintf(MAXDESCSIZE, "Ramdisk [%s]", &filename[10]);
51     boot_add_floppy(drive_g, desc, bootprio_find_named_rom(filename, 0));
52 }
53
54 static int
55 ramdisk_copy(struct disk_op_s *op, int iswrite)
56 {
57     u32 offset = GET_GLOBAL(op->drive_g->cntl_id);
58     offset += (u32)op->lba * DISK_SECTOR_SIZE;
59     u64 opd = GDT_DATA | GDT_LIMIT(0xfffff) | GDT_BASE((u32)op->buf_fl);
60     u64 ramd = GDT_DATA | GDT_LIMIT(0xfffff) | GDT_BASE(offset);
61
62     u64 gdt[6];
63     if (iswrite) {
64         gdt[2] = opd;
65         gdt[3] = ramd;
66     } else {
67         gdt[2] = ramd;
68         gdt[3] = opd;
69     }
70
71     // Call int 1587 to copy data.
72     struct bregs br;
73     memset(&br, 0, sizeof(br));
74     br.flags = F_CF|F_IF;
75     br.ah = 0x87;
76     br.es = GET_SEG(SS);
77     br.si = (u32)gdt;
78     br.cx = op->count * DISK_SECTOR_SIZE / 2;
79     call16_int(0x15, &br);
80
81     if (br.flags & F_CF)
82         return DISK_RET_EBADTRACK;
83     return DISK_RET_SUCCESS;
84 }
85
86 int
87 process_ramdisk_op(struct disk_op_s *op)
88 {
89     if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH || !CONFIG_FLASH_FLOPPY)
90         return 0;
91
92     switch (op->command) {
93     case CMD_READ:
94         return ramdisk_copy(op, 0);
95     case CMD_WRITE:
96         return ramdisk_copy(op, 1);
97     case CMD_VERIFY:
98     case CMD_FORMAT:
99     case CMD_RESET:
100         return DISK_RET_SUCCESS;
101     default:
102         op->count = 0;
103         return DISK_RET_EPARAM;
104     }
105 }