| /* SPDX-License-Identifier: MIT */ |
| |
| #ifndef HV_H |
| #define HV_H |
| |
| #include "exception.h" |
| #include "iodev.h" |
| #include "types.h" |
| #include "uartproxy.h" |
| |
| typedef bool(hv_hook_t)(struct exc_info *ctx, u64 addr, u64 *val, bool write, int width); |
| |
| #define MMIO_EVT_ATTR GENMASK(31, 24) |
| #define MMIO_EVT_CPU GENMASK(23, 16) |
| #define MMIO_EVT_SH GENMASK(15, 14) |
| #define MMIO_EVT_MULTI BIT(6) |
| #define MMIO_EVT_WRITE BIT(5) |
| #define MMIO_EVT_WIDTH GENMASK(4, 0) |
| |
| struct hv_evt_mmiotrace { |
| u32 flags; |
| u32 reserved; |
| u64 pc; |
| u64 addr; |
| u64 data; |
| }; |
| |
| struct hv_evt_irqtrace { |
| u32 flags; |
| u16 type; |
| u16 num; |
| }; |
| |
| #define HV_MAX_RW_SIZE 64 |
| #define HV_MAX_RW_WORDS (HV_MAX_RW_SIZE >> 3) |
| |
| struct hv_vm_proxy_hook_data { |
| u32 flags; |
| u32 id; |
| u64 addr; |
| u64 data[HV_MAX_RW_WORDS]; |
| }; |
| |
| typedef enum _hv_entry_type { |
| HV_HOOK_VM = 1, |
| HV_VTIMER, |
| HV_USER_INTERRUPT, |
| HV_WDT_BARK, |
| HV_CPU_SWITCH, |
| HV_VIRTIO, |
| HV_PANIC, |
| } hv_entry_type; |
| |
| /* VM */ |
| void hv_pt_init(void); |
| int hv_map(u64 from, u64 to, u64 size, u64 incr); |
| int hv_unmap(u64 from, u64 size); |
| int hv_map_hw(u64 from, u64 to, u64 size); |
| int hv_map_sw(u64 from, u64 to, u64 size); |
| int hv_map_hook(u64 from, hv_hook_t *hook, u64 size); |
| u64 hv_translate(u64 addr, bool s1only, bool w, u64 *par_out); |
| u64 hv_pt_walk(u64 addr); |
| bool hv_handle_dabort(struct exc_info *ctx); |
| bool hv_pa_write(struct exc_info *ctx, u64 addr, u64 *val, int width); |
| bool hv_pa_read(struct exc_info *ctx, u64 addr, u64 *val, int width); |
| bool hv_pa_rw(struct exc_info *ctx, u64 addr, u64 *val, bool write, int width); |
| |
| /* AIC events through tracing the MMIO event address */ |
| bool hv_trace_irq(u32 type, u32 num, u32 count, u32 flags); |
| |
| /* Virtual peripherals */ |
| void hv_vuart_poll(void); |
| void hv_map_vuart(u64 base, int irq, iodev_id_t iodev); |
| struct virtio_conf; |
| void hv_map_virtio(u64 base, struct virtio_conf *conf); |
| void virtio_put_buffer(u64 base, int qu, u32 id, u32 len); |
| |
| /* Exceptions */ |
| void hv_exc_proxy(struct exc_info *ctx, uartproxy_boot_reason_t reason, u32 type, void *extra); |
| void hv_set_time_stealing(bool enabled, bool reset); |
| void hv_add_time(s64 time); |
| |
| /* WDT */ |
| void hv_wdt_pet(void); |
| void hv_wdt_suspend(void); |
| void hv_wdt_resume(void); |
| void hv_wdt_init(void); |
| void hv_wdt_start(int cpu); |
| void hv_wdt_stop(void); |
| void hv_wdt_breadcrumb(char c); |
| void hv_do_panic(void); |
| |
| #define hv_panic(fmt, ...) \ |
| do { \ |
| debug_printf("HV panic:" fmt, ##__VA_ARGS__); \ |
| hv_do_panic(); \ |
| flush_and_reboot(); \ |
| } while (0) |
| |
| /* Utilities */ |
| void hv_write_hcr(u64 val); |
| u64 hv_get_spsr(void); |
| void hv_set_spsr(u64 val); |
| u64 hv_get_esr(void); |
| u64 hv_get_far(void); |
| u64 hv_get_elr(void); |
| u64 hv_get_afsr1(void); |
| void hv_set_elr(u64 val); |
| |
| /* HV main */ |
| void hv_init(void); |
| void hv_start(void *entry, u64 regs[4]); |
| void hv_start_secondary(int cpu, void *entry, u64 regs[4]); |
| void hv_exit_cpu(int cpu); |
| void hv_rendezvous(void); |
| bool hv_switch_cpu(int cpu); |
| void hv_pin_cpu(int cpu); |
| void hv_arm_tick(bool secondary); |
| void hv_rearm(void); |
| void hv_maybe_exit(void); |
| void hv_tick(struct exc_info *ctx); |
| |
| #endif |