1/* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12/* 13 * Copyright 2025 Oxide Computer Company 14 */ 15 16#include <sys/asm_linkage.h> 17#include "payload_common.h" 18 19/* void outb(uint16_t port, uint8_t val) */ 20ENTRY(outb) 21 movw %di, %dx 22 movb %sil, %al 23 outb (%dx) 24 ret 25SET_SIZE(outb) 26 27/* void outw(uint16_t port, uint16_t val) */ 28ENTRY(outw) 29 movw %di, %dx 30 movw %si, %ax 31 outw (%dx) 32 ret 33SET_SIZE(outb) 34 35/* void outl(uint16_t port, uint32_t val) */ 36ENTRY(outl) 37 movw %di, %dx 38 movl %esi, %eax 39 outl (%dx) 40 ret 41SET_SIZE(outl) 42 43/* uint8_t inb(uint16_t port) */ 44ENTRY(inb) 45 movw %di, %dx 46 inb (%dx) 47 ret 48SET_SIZE(inb) 49 50/* uint16_t inw(uint16_t port) */ 51ENTRY(inw) 52 movw %di, %dx 53 inw (%dx) 54 ret 55SET_SIZE(inw) 56 57/* uint32_t inl(uint16_t port) */ 58ENTRY(inl) 59 movw %di, %dx 60 inl (%dx) 61 ret 62SET_SIZE(inl) 63 64/* uint64_t rdmsr(uint32_t msr) */ 65ENTRY(rdmsr) 66 movl %edi, %ecx 67 rdmsr 68 shlq $32, %rdx 69 orq %rdx, %rax 70 ret 71SET_SIZE(rdmsr) 72 73/* void wrmsr(uint32_t msr, uint64_t val) */ 74ENTRY(wrmsr) 75 movq %rsi, %rdx 76 shrq $32, %rdx 77 movl %esi, %eax 78 movl %edi, %ecx 79 wrmsr 80 ret 81SET_SIZE(wrmsr) 82 83/* void cpuid(uint32_t in_eax, uint32_t in_ecx, uint32_t *out_regs) */ 84ENTRY(cpuid) 85 pushq %rbx 86 movl %edi, %eax 87 movl %esi, %ecx 88 movq %rdx, %r8 89 cpuid 90 movl %eax, (%r8) 91 movl %ebx, 4(%r8) 92 movl %ecx, 8(%r8) 93 movl %edx, 12(%r8) 94 popq %rbx 95 ret 96SET_SIZE(cpuid) 97 98/* uint64_t rdtsc(void) */ 99ENTRY(rdtsc) 100 rdtsc 101 shlq $32, %rdx 102 orq %rdx, %rax 103 ret 104SET_SIZE(rdtsc) 105 106/* void ud2a(void) */ 107ENTRY(ud2a) 108 ud2a 109SET_SIZE(ud2a) 110 111/* void setcr4(uint64_t) */ 112ENTRY(setcr4) 113 movq %rdi, %cr4 114 ret 115SET_SIZE(setcr4) 116 117/* uint64_t getcr4(void) */ 118ENTRY(getcr4) 119 movq %cr4, %rax 120 ret 121SET_SIZE(getcr4) 122 123/* void setxcr(uint32_t, uint64_t) */ 124ENTRY(setxcr) 125 movq %rsi, %rdx 126 shrq $32, %rdx 127 movl %esi, %eax 128 movl %edi, %ecx 129 #xsetbv 130 .byte 0x0f,0x01,0xd1 131 ret 132SET_SIZE(setxcr) 133 134/* uint64_t getxcr(uint32_t) */ 135ENTRY(getxcr) 136 movl %edi, %ecx 137 #xgetbv 138 .byte 0x0f,0x01,0xd0 139 shlq $32, %rdx 140 orq %rdx, %rax 141 ret 142SET_SIZE(getxcr) 143 144/* void test_result_pass(void) */ 145ENTRY(test_result_pass) 146 movl $IOP_TEST_RESULT, %edi 147 movl $TEST_RESULT_PASS, %esi 148 call outb 149 ret 150SET_SIZE(test_result_pass) 151 152/* void test_result_fail(void) */ 153ENTRY(test_result_fail) 154 movl $IOP_TEST_RESULT, %edi 155 movl $TEST_RESULT_FAIL, %esi 156 call outb 157 ret 158SET_SIZE(test_result_fail) 159 160/* void test_msg(const char *) */ 161ENTRY(test_msg) 162 /* 163 * Message address is assumed to be in lower 32-bits, since that is where 164 * the payload is currently being mapped. 165 */ 166 movl %edi, %esi 167 movl $IOP_TEST_MSG, %edi 168 call outl 169 170 ret 171SET_SIZE(test_msg) 172