blob: e7ba212314a6e642c53eb27a1cb883eebe7193b6 [file] [log] [blame] [raw]
/*
* VM definitions
*
* Copyright (c) 2016-2017 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "json.h"
typedef struct FBDevice FBDevice;
typedef void SimpleFBDrawFunc(FBDevice *fb_dev, void *opaque,
int x, int y, int w, int h);
struct FBDevice {
/* the following is set by the device */
int width;
int height;
int stride; /* current stride in bytes */
uint8_t *fb_data; /* current pointer to the pixel data */
int fb_size; /* frame buffer memory size (info only) */
void *device_opaque;
void (*refresh)(struct FBDevice *fb_dev,
SimpleFBDrawFunc *redraw_func, void *opaque);
};
#define MAX_DRIVE_DEVICE 4
#define MAX_FS_DEVICE 4
#define MAX_ETH_DEVICE 1
#define VM_CONFIG_VERSION 1
typedef enum {
VM_FILE_BIOS,
VM_FILE_VGA_BIOS,
VM_FILE_KERNEL,
VM_FILE_INITRD,
VM_FILE_COUNT,
} VMFileTypeEnum;
typedef struct {
char *filename;
uint8_t *buf;
int len;
} VMFileEntry;
typedef struct {
char *device;
char *filename;
BlockDevice *block_dev;
} VMDriveEntry;
typedef struct {
char *device;
char *tag; /* 9p mount tag */
char *filename;
FSDevice *fs_dev;
} VMFSEntry;
typedef struct {
char *driver;
char *ifname;
EthernetDevice *net;
} VMEthEntry;
typedef struct VirtMachineClass VirtMachineClass;
typedef struct {
char *cfg_filename;
const VirtMachineClass *vmc;
char *machine_name;
uint64_t ram_size;
BOOL rtc_real_time;
BOOL rtc_local_time;
char *display_device; /* NULL means no display */
int width, height; /* graphic width & height */
CharacterDevice *console;
VMDriveEntry tab_drive[MAX_DRIVE_DEVICE];
int drive_count;
VMFSEntry tab_fs[MAX_FS_DEVICE];
int fs_count;
VMEthEntry tab_eth[MAX_ETH_DEVICE];
int eth_count;
char *cmdline; /* bios or kernel command line */
BOOL accel_enable; /* enable acceleration (KVM) */
char *input_device; /* NULL means no input */
/* kernel, bios and other auxiliary files */
VMFileEntry files[VM_FILE_COUNT];
} VirtMachineParams;
typedef struct VirtMachine {
const VirtMachineClass *vmc;
/* network */
EthernetDevice *net;
/* console */
VIRTIODevice *console_dev;
CharacterDevice *console;
/* graphics */
FBDevice *fb_dev;
} VirtMachine;
struct VirtMachineClass {
const char *machine_names;
void (*virt_machine_set_defaults)(VirtMachineParams *p);
VirtMachine *(*virt_machine_init)(const VirtMachineParams *p);
void (*virt_machine_end)(VirtMachine *s);
int (*virt_machine_get_sleep_duration)(VirtMachine *s, int delay);
void (*virt_machine_interp)(VirtMachine *s, int max_exec_cycle);
BOOL (*vm_mouse_is_absolute)(VirtMachine *s);
void (*vm_send_mouse_event)(VirtMachine *s1, int dx, int dy, int dz,
unsigned int buttons);
void (*vm_send_key_event)(VirtMachine *s1, BOOL is_down, uint16_t key_code);
};
extern const VirtMachineClass riscv_machine_class;
extern const VirtMachineClass pc_machine_class;
// SDL may has exported a same symbol name
#define vm_error tinyemu_vm_error
void __attribute__((format(printf, 1, 2))) vm_error(const char *fmt, ...);
int vm_get_int(JSONValue obj, const char *name, int *pval);
int vm_get_int_opt(JSONValue obj, const char *name, int *pval, int def_val);
void virt_machine_set_defaults(VirtMachineParams *p);
void virt_machine_load_config_file(VirtMachineParams *p,
const char *filename,
void (*start_cb)(void *opaque),
void *opaque);
void vm_add_cmdline(VirtMachineParams *p, const char *cmdline);
char *get_file_path(const char *base_filename, const char *filename);
void virt_machine_free_config(VirtMachineParams *p);
VirtMachine *virt_machine_init(const VirtMachineParams *p);
void virt_machine_end(VirtMachine *s);
static inline int virt_machine_get_sleep_duration(VirtMachine *s, int delay)
{
return s->vmc->virt_machine_get_sleep_duration(s, delay);
}
static inline void virt_machine_interp(VirtMachine *s, int max_exec_cycle)
{
s->vmc->virt_machine_interp(s, max_exec_cycle);
}
static inline BOOL vm_mouse_is_absolute(VirtMachine *s)
{
return s->vmc->vm_mouse_is_absolute(s);
}
static inline void vm_send_mouse_event(VirtMachine *s1, int dx, int dy, int dz,
unsigned int buttons)
{
s1->vmc->vm_send_mouse_event(s1, dx, dy, dz, buttons);
}
static inline void vm_send_key_event(VirtMachine *s1, BOOL is_down, uint16_t key_code)
{
s1->vmc->vm_send_key_event(s1, is_down, key_code);
}
/* gui */
void sdl_refresh(VirtMachine *m);
void sdl_init(int width, int height);
/* simplefb.c */
typedef struct SimpleFBState SimpleFBState;
SimpleFBState *simplefb_init(PhysMemoryMap *map, uint64_t phys_addr,
FBDevice *fb_dev, int width, int height);
void simplefb_refresh(FBDevice *fb_dev,
SimpleFBDrawFunc *redraw_func, void *opaque,
PhysMemoryRange *mem_range,
int fb_page_count);
/* vga.c */
typedef struct VGAState VGAState;
VGAState *pci_vga_init(PCIBus *bus, FBDevice *fb_dev,
int width, int height,
const uint8_t *vga_rom_buf, int vga_rom_size);
/* block_net.c */
BlockDevice *block_device_init_http(const char *url,
int max_cache_size_kb,
void (*start_cb)(void *opaque),
void *start_opaque);