xref: /kvmtool/mips/kvm.c (revision 7281a8db199b95e47ff80c73765709372cd08f1e)
1*7281a8dbSDavid Daney #include "kvm/kvm.h"
2*7281a8dbSDavid Daney #include "kvm/ioport.h"
3*7281a8dbSDavid Daney #include "kvm/virtio-console.h"
4*7281a8dbSDavid Daney 
5*7281a8dbSDavid Daney #include <linux/kvm.h>
6*7281a8dbSDavid Daney 
7*7281a8dbSDavid Daney #include <ctype.h>
8*7281a8dbSDavid Daney #include <unistd.h>
9*7281a8dbSDavid Daney 
10*7281a8dbSDavid Daney struct kvm_ext kvm_req_ext[] = {
11*7281a8dbSDavid Daney 	{ 0, 0 }
12*7281a8dbSDavid Daney };
13*7281a8dbSDavid Daney 
14*7281a8dbSDavid Daney void kvm__arch_read_term(struct kvm *kvm)
15*7281a8dbSDavid Daney {
16*7281a8dbSDavid Daney 	virtio_console__inject_interrupt(kvm);
17*7281a8dbSDavid Daney }
18*7281a8dbSDavid Daney 
19*7281a8dbSDavid Daney void kvm__init_ram(struct kvm *kvm)
20*7281a8dbSDavid Daney {
21*7281a8dbSDavid Daney 	u64	phys_start, phys_size;
22*7281a8dbSDavid Daney 	void	*host_mem;
23*7281a8dbSDavid Daney 
24*7281a8dbSDavid Daney 	phys_start = 0;
25*7281a8dbSDavid Daney 	phys_size  = kvm->ram_size;
26*7281a8dbSDavid Daney 	host_mem   = kvm->ram_start;
27*7281a8dbSDavid Daney 
28*7281a8dbSDavid Daney 	kvm__register_mem(kvm, phys_start, phys_size, host_mem);
29*7281a8dbSDavid Daney }
30*7281a8dbSDavid Daney 
31*7281a8dbSDavid Daney void kvm__arch_delete_ram(struct kvm *kvm)
32*7281a8dbSDavid Daney {
33*7281a8dbSDavid Daney 	munmap(kvm->ram_start, kvm->ram_size);
34*7281a8dbSDavid Daney }
35*7281a8dbSDavid Daney 
36*7281a8dbSDavid Daney void kvm__arch_set_cmdline(char *cmdline, bool video)
37*7281a8dbSDavid Daney {
38*7281a8dbSDavid Daney 
39*7281a8dbSDavid Daney }
40*7281a8dbSDavid Daney 
41*7281a8dbSDavid Daney /* Architecture-specific KVM init */
42*7281a8dbSDavid Daney void kvm__arch_init(struct kvm *kvm, const char *hugetlbfs_path, u64 ram_size)
43*7281a8dbSDavid Daney {
44*7281a8dbSDavid Daney 	int ret;
45*7281a8dbSDavid Daney 
46*7281a8dbSDavid Daney 	kvm->ram_start = mmap_anon_or_hugetlbfs(kvm, hugetlbfs_path, ram_size);
47*7281a8dbSDavid Daney 	kvm->ram_size = ram_size;
48*7281a8dbSDavid Daney 
49*7281a8dbSDavid Daney 	if (kvm->ram_start == MAP_FAILED)
50*7281a8dbSDavid Daney 		die("out of memory");
51*7281a8dbSDavid Daney 
52*7281a8dbSDavid Daney 	madvise(kvm->ram_start, kvm->ram_size, MADV_MERGEABLE);
53*7281a8dbSDavid Daney 
54*7281a8dbSDavid Daney 	ret = ioctl(kvm->vm_fd, KVM_CREATE_IRQCHIP);
55*7281a8dbSDavid Daney 	if (ret < 0)
56*7281a8dbSDavid Daney 		die_perror("KVM_CREATE_IRQCHIP ioctl");
57*7281a8dbSDavid Daney }
58*7281a8dbSDavid Daney 
59*7281a8dbSDavid Daney void kvm__irq_line(struct kvm *kvm, int irq, int level)
60*7281a8dbSDavid Daney {
61*7281a8dbSDavid Daney 	struct kvm_irq_level irq_level;
62*7281a8dbSDavid Daney 	int ret;
63*7281a8dbSDavid Daney 
64*7281a8dbSDavid Daney 	irq_level.irq = irq;
65*7281a8dbSDavid Daney 	irq_level.level = level ? 1 : 0;
66*7281a8dbSDavid Daney 
67*7281a8dbSDavid Daney 	ret = ioctl(kvm->vm_fd, KVM_IRQ_LINE, &irq_level);
68*7281a8dbSDavid Daney 	if (ret < 0)
69*7281a8dbSDavid Daney 		die_perror("KVM_IRQ_LINE ioctl");
70*7281a8dbSDavid Daney }
71*7281a8dbSDavid Daney 
72*7281a8dbSDavid Daney void kvm__irq_trigger(struct kvm *kvm, int irq)
73*7281a8dbSDavid Daney {
74*7281a8dbSDavid Daney 	struct kvm_irq_level irq_level;
75*7281a8dbSDavid Daney 	int ret;
76*7281a8dbSDavid Daney 
77*7281a8dbSDavid Daney 	irq_level.irq = irq;
78*7281a8dbSDavid Daney 	irq_level.level = 1;
79*7281a8dbSDavid Daney 
80*7281a8dbSDavid Daney 	ret = ioctl(kvm->vm_fd, KVM_IRQ_LINE, &irq_level);
81*7281a8dbSDavid Daney 	if (ret < 0)
82*7281a8dbSDavid Daney 		die_perror("KVM_IRQ_LINE ioctl");
83*7281a8dbSDavid Daney }
84*7281a8dbSDavid Daney 
85*7281a8dbSDavid Daney void ioport__setup_arch(struct kvm *kvm)
86*7281a8dbSDavid Daney {
87*7281a8dbSDavid Daney }
88*7281a8dbSDavid Daney 
89*7281a8dbSDavid Daney bool kvm__arch_cpu_supports_vm(void)
90*7281a8dbSDavid Daney {
91*7281a8dbSDavid Daney 	return true;
92*7281a8dbSDavid Daney }
93*7281a8dbSDavid Daney bool kvm__load_firmware(struct kvm *kvm, const char *firmware_filename)
94*7281a8dbSDavid Daney {
95*7281a8dbSDavid Daney 	return false;
96*7281a8dbSDavid Daney }
97*7281a8dbSDavid Daney int kvm__arch_setup_firmware(struct kvm *kvm)
98*7281a8dbSDavid Daney {
99*7281a8dbSDavid Daney 	return 0;
100*7281a8dbSDavid Daney }
101*7281a8dbSDavid Daney 
102*7281a8dbSDavid Daney /* Load at the 1M point. */
103*7281a8dbSDavid Daney #define KERNEL_LOAD_ADDR 0x1000000
104*7281a8dbSDavid Daney int load_flat_binary(struct kvm *kvm, int fd_kernel, int fd_initrd, const char *kernel_cmdline)
105*7281a8dbSDavid Daney {
106*7281a8dbSDavid Daney 	void *p;
107*7281a8dbSDavid Daney 	void *k_start;
108*7281a8dbSDavid Daney 	int nr;
109*7281a8dbSDavid Daney 
110*7281a8dbSDavid Daney 	if (lseek(fd_kernel, 0, SEEK_SET) < 0)
111*7281a8dbSDavid Daney 		die_perror("lseek");
112*7281a8dbSDavid Daney 
113*7281a8dbSDavid Daney 	p = k_start = guest_flat_to_host(kvm, KERNEL_LOAD_ADDR);
114*7281a8dbSDavid Daney 
115*7281a8dbSDavid Daney 	while ((nr = read(fd_kernel, p, 65536)) > 0)
116*7281a8dbSDavid Daney 		p += nr;
117*7281a8dbSDavid Daney 
118*7281a8dbSDavid Daney 	kvm->arch.is64bit = true;
119*7281a8dbSDavid Daney 	kvm->arch.entry_point = 0xffffffff81000000ull;
120*7281a8dbSDavid Daney 
121*7281a8dbSDavid Daney 	pr_info("Loaded kernel to 0x%x (%ld bytes)", KERNEL_LOAD_ADDR, (long int)(p - k_start));
122*7281a8dbSDavid Daney 
123*7281a8dbSDavid Daney 	return true;
124*7281a8dbSDavid Daney }
125*7281a8dbSDavid Daney 
126*7281a8dbSDavid Daney void ioport__map_irq(u8 *irq)
127*7281a8dbSDavid Daney {
128*7281a8dbSDavid Daney }
129