:: limine / common / lib / misc.h 4.6 KB raw

1
#ifndef LIB__MISC_H__
2
#define LIB__MISC_H__
3
4
#include <stddef.h>
5
#include <stdint.h>
6
#include <stdbool.h>
7
#include <stdnoreturn.h>
8
#include <fs/file.h>
9
#include <lib/part.h>
10
#include <lib/libc.h>
11
#if defined (UEFI)
12
#  include <efi.h>
13
#  if defined (__riscv)
14
#    include <efi/protocol/riscv/efiboot.h>
15
#  endif
16
#endif
17
18
#if defined (UEFI)
19
extern EFI_SYSTEM_TABLE *gST;
20
extern EFI_BOOT_SERVICES *gBS;
21
extern EFI_RUNTIME_SERVICES *gRT;
22
extern EFI_HANDLE efi_image_handle;
23
extern EFI_MEMORY_DESCRIPTOR *efi_mmap;
24
extern UINTN efi_mmap_size, efi_desc_size, efi_mmap_key;
25
extern UINT32 efi_desc_ver;
26
27
extern bool efi_boot_services_exited;
28
bool efi_exit_boot_services(void);
29
30
bool is_efi_serial_present(void);
31
#endif
32
33
void *get_device_tree_blob(const char *config, size_t extra_size, bool measure);
34
35
extern struct volume *boot_volume;
36
37
#if defined (BIOS)
38
extern bool stage3_loaded;
39
#endif
40
41
extern bool quiet, serial, editor_enabled, help_hidden, hash_mismatch_panic, secure_boot_active, measured_boot;
42
43
extern uint64_t usec_at_bootloader_entry;
44
45
bool parse_resolution(size_t *width, size_t *height, size_t *bpp, const char *buf);
46
47
bool get_absolute_path(char *path_ptr, const char *path, const char *pwd, size_t size);
48
49
uint64_t sqrt(uint64_t a_nInput);
50
size_t get_trailing_zeros(uint64_t val);
51
52
int digit_to_int(char c);
53
uint8_t bcd_to_int(uint8_t val);
54
uint8_t int_to_bcd(uint8_t val);
55
56
noreturn void panic(bool allow_menu, const char *fmt, ...);
57
58
int pit_sleep_and_quit_on_keypress(int seconds);
59
int pit_sleep_ms_and_quit_on_keypress(uint64_t milliseconds);
60
61
uint64_t strtoui(const char *s, const char **end, int base);
62
63
#define MIN(a, b) ({ \
64
    __auto_type MIN_a = (a); \
65
    __auto_type MIN_b = (b); \
66
    MIN_a > MIN_b ? MIN_b : MIN_a; \
67
})
68
69
#define MAX(a, b) ({ \
70
    __auto_type MAX_a = (a); \
71
    __auto_type MAX_b = (b); \
72
    MAX_a > MAX_b ? MAX_a : MAX_b; \
73
})
74
75
#define CHECKED_ADD(a, b, onerror) ({ \
76
    __auto_type CHECKED_ADD_a = (a); \
77
    __auto_type CHECKED_ADD_b = (b); \
78
    typeof(CHECKED_ADD_a + CHECKED_ADD_b) CHECKED_ADD_res; \
79
    if (__builtin_add_overflow(CHECKED_ADD_a, CHECKED_ADD_b, &CHECKED_ADD_res)) { \
80
        onerror; \
81
    } \
82
    CHECKED_ADD_res; \
83
})
84
85
#define CHECKED_MUL(a, b, onerror) ({ \
86
    __auto_type CHECKED_MUL_a = (a); \
87
    __auto_type CHECKED_MUL_b = (b); \
88
    typeof(CHECKED_MUL_a * CHECKED_MUL_b) CHECKED_MUL_res; \
89
    if (__builtin_mul_overflow(CHECKED_MUL_a, CHECKED_MUL_b, &CHECKED_MUL_res)) { \
90
        onerror; \
91
    } \
92
    CHECKED_MUL_res; \
93
})
94
95
#define DIV_ROUNDUP(a, b, onerror) ({ \
96
    __auto_type DIV_ROUNDUP_a = (a); \
97
    __auto_type DIV_ROUNDUP_b = (b); \
98
    CHECKED_ADD(DIV_ROUNDUP_a, DIV_ROUNDUP_b - 1, onerror) / DIV_ROUNDUP_b; \
99
})
100
101
#define ALIGN_UP(x, a, onerror) ({ \
102
    __auto_type ALIGN_UP_value = (x); \
103
    __auto_type ALIGN_UP_align = (a); \
104
    ALIGN_UP_value = DIV_ROUNDUP(ALIGN_UP_value, ALIGN_UP_align, onerror) * ALIGN_UP_align; \
105
    ALIGN_UP_value; \
106
})
107
108
#define ALIGN_DOWN(x, a) ({ \
109
    __auto_type ALIGN_DOWN_value = (x); \
110
    __auto_type ALIGN_DOWN_align = (a); \
111
    ALIGN_DOWN_value = (ALIGN_DOWN_value / ALIGN_DOWN_align) * ALIGN_DOWN_align; \
112
    ALIGN_DOWN_value; \
113
})
114
115
#define SIZEOF_ARRAY(array) (sizeof(array) / sizeof(array[0]))
116
117
typedef char symbol[];
118
119
noreturn void stage3_common(void);
120
121
#if defined (__x86_64__) || defined (__i386__)
122
noreturn void common_spinup(void *fnptr, int args, ...);
123
#elif defined (__aarch64__)
124
noreturn void enter_in_el1(uint64_t entry, uint64_t sp, uint64_t sctlr,
125
                           uint64_t mair, uint64_t tcr, uint64_t ttbr0,
126
                           uint64_t ttbr1, uint64_t target_x0);
127
noreturn void enter_in_el2(uint64_t entry, uint64_t sp, uint64_t sctlr,
128
                           uint64_t mair, uint64_t tcr, uint64_t ttbr0,
129
                           uint64_t ttbr1, uint64_t target_x0);
130
#elif defined (__riscv)
131
noreturn void riscv_spinup(uint64_t entry, uint64_t sp, uint64_t satp, uint64_t direct_map_offset);
132
#if defined (UEFI)
133
RISCV_EFI_BOOT_PROTOCOL *get_riscv_boot_protocol(void);
134
#endif
135
#elif defined (__loongarch64)
136
noreturn void loongarch_spinup(uint64_t entry, uint64_t sp, uint64_t pgdl,
137
                               uint64_t pgdh, uint64_t direct_map_offset);
138
#else
139
#error Unknown architecture
140
#endif
141
142
#define no_unwind __attribute__((section(".no_unwind")))
143
144
#define MEM_RANGE_X 1
145
#define MEM_RANGE_W 2
146
#define MEM_RANGE_R 4
147
148
struct mem_range {
149
    uint64_t base;
150
    uint64_t length;
151
    uint64_t permissions;
152
};
153
154
static inline const char *current_firmware(void) {
155
#if defined (UEFI)
156
    return "UEFI";
157
#elif defined (BIOS)
158
    return "BIOS";
159
#else
160
#error "Unspecified firmware type"
161
#endif
162
}
163
164
#endif
tab: 248 wrap: offon