1*5ad8db5eSPekka Enberg #include "kvm/kvm.h" 2*5ad8db5eSPekka Enberg 3*5ad8db5eSPekka Enberg #include "kvm/util.h" 4*5ad8db5eSPekka Enberg 5*5ad8db5eSPekka Enberg #include <sys/types.h> 6*5ad8db5eSPekka Enberg #include <sys/stat.h> 7*5ad8db5eSPekka Enberg #include <stdbool.h> 8*5ad8db5eSPekka Enberg #include <fcntl.h> 9*5ad8db5eSPekka Enberg 10*5ad8db5eSPekka Enberg #define BIOS_SELECTOR 0xf000 11*5ad8db5eSPekka Enberg #define BIOS_IP 0xfff0 12*5ad8db5eSPekka Enberg #define BIOS_SP 0x8000 13*5ad8db5eSPekka Enberg 14*5ad8db5eSPekka Enberg bool kvm__load_firmware(struct kvm *kvm, const char *firmware_filename) 15*5ad8db5eSPekka Enberg { 16*5ad8db5eSPekka Enberg struct stat st; 17*5ad8db5eSPekka Enberg void *p; 18*5ad8db5eSPekka Enberg int fd; 19*5ad8db5eSPekka Enberg int nr; 20*5ad8db5eSPekka Enberg 21*5ad8db5eSPekka Enberg fd = open(firmware_filename, O_RDONLY); 22*5ad8db5eSPekka Enberg if (fd < 0) 23*5ad8db5eSPekka Enberg return false; 24*5ad8db5eSPekka Enberg 25*5ad8db5eSPekka Enberg if (fstat(fd, &st)) 26*5ad8db5eSPekka Enberg return false; 27*5ad8db5eSPekka Enberg 28*5ad8db5eSPekka Enberg if (st.st_size > MB_BIOS_SIZE) 29*5ad8db5eSPekka Enberg die("firmware image %s is too big to fit in memory (%lu KB).\n", firmware_filename, st.st_size / 1024); 30*5ad8db5eSPekka Enberg 31*5ad8db5eSPekka Enberg p = guest_flat_to_host(kvm, MB_BIOS_BEGIN); 32*5ad8db5eSPekka Enberg 33*5ad8db5eSPekka Enberg while ((nr = read(fd, p, st.st_size)) > 0) 34*5ad8db5eSPekka Enberg p += nr; 35*5ad8db5eSPekka Enberg 36*5ad8db5eSPekka Enberg kvm->boot_selector = BIOS_SELECTOR; 37*5ad8db5eSPekka Enberg kvm->boot_ip = BIOS_IP; 38*5ad8db5eSPekka Enberg kvm->boot_sp = BIOS_SP; 39*5ad8db5eSPekka Enberg 40*5ad8db5eSPekka Enberg return true; 41*5ad8db5eSPekka Enberg } 42