/* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Pushes a 32-bit register onto the stack. * * There are two possible code sections where this code can be included: * .code32 and .code64 * * Doing a `push %eax` while in a .code64 section will result in a compiler * error. This macro manually pushes the 32-bit register onto the stack so we * can share the code between 32 and 64 bit builds. */ .macro pushr reg:req #if ENV_X86_64 movl $0, -4(%esp) movl \reg, -8(%esp) sub $8, %esp #else push \reg #endif .endm /* Push struct cpu_info */ .macro push_cpu_info index=$0 pushr \index /* index (size_t) */ pushr $0 /* *cpu */ .endm /* Push struct per_cpu_segment_data */ .macro push_per_cpu_segment_data cpu_info_pointer=%esp pushr \cpu_info_pointer /* *cpu_info */ .endm /* * Sets the base address in the segment descriptor array. * * A segment descriptor has the following structure: * struct { * uint16_t segment_limit_0_15; * uint16_t base_address_0_15; * uint8_t base_address_16_23; * uint8_t attrs[2]; * uint8_t base_address_24_31; * }; * * @desc_array: Address of the descriptor table * @base: Address to set in the descriptor * @desc_index: Index of the descriptor in the table. Defaults to 0. Must be a * register if specified. * * Clobbers %eax, %ebx. */ .macro set_segment_descriptor_base desc_array:req, base:req, desc_index mov \base, %eax mov \desc_array, %ebx .ifb \desc_index movw %ax, 2(%ebx) shr $16, %eax movb %al, 4(%ebx) shr $8, %eax movb %al, 7(%ebx) .else movw %ax, 2(%ebx, \desc_index, 8) shr $16, %eax movb %al, 4(%ebx, \desc_index, 8) shr $8, %eax movb %al, 7(%ebx, \desc_index, 8) .endif .endm