162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/* -*- linux-c -*- ------------------------------------------------------- *
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci *   Copyright (C) 1991, 1992 Linus Torvalds
562306a36Sopenharmony_ci *   Copyright 2007 rPath, Inc. - All Rights Reserved
662306a36Sopenharmony_ci *   Copyright 2009 Intel Corporation; author H. Peter Anvin
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * ----------------------------------------------------------------------- */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci/*
1162306a36Sopenharmony_ci * Header file for the real-mode kernel code
1262306a36Sopenharmony_ci */
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#ifndef BOOT_BOOT_H
1562306a36Sopenharmony_ci#define BOOT_BOOT_H
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#define STACK_SIZE	1024	/* Minimum number of bytes for stack */
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#ifndef __ASSEMBLY__
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#include <linux/stdarg.h>
2262306a36Sopenharmony_ci#include <linux/types.h>
2362306a36Sopenharmony_ci#include <linux/edd.h>
2462306a36Sopenharmony_ci#include <asm/setup.h>
2562306a36Sopenharmony_ci#include <asm/asm.h>
2662306a36Sopenharmony_ci#include "bitops.h"
2762306a36Sopenharmony_ci#include "ctype.h"
2862306a36Sopenharmony_ci#include "cpuflags.h"
2962306a36Sopenharmony_ci#include "io.h"
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci/* Useful macros */
3262306a36Sopenharmony_ci#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ciextern struct setup_header hdr;
3562306a36Sopenharmony_ciextern struct boot_params boot_params;
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci#define cpu_relax()	asm volatile("rep; nop")
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_cistatic inline void io_delay(void)
4062306a36Sopenharmony_ci{
4162306a36Sopenharmony_ci	const u16 DELAY_PORT = 0x80;
4262306a36Sopenharmony_ci	outb(0, DELAY_PORT);
4362306a36Sopenharmony_ci}
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci/* These functions are used to reference data in other segments. */
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cistatic inline u16 ds(void)
4862306a36Sopenharmony_ci{
4962306a36Sopenharmony_ci	u16 seg;
5062306a36Sopenharmony_ci	asm("movw %%ds,%0" : "=rm" (seg));
5162306a36Sopenharmony_ci	return seg;
5262306a36Sopenharmony_ci}
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_cistatic inline void set_fs(u16 seg)
5562306a36Sopenharmony_ci{
5662306a36Sopenharmony_ci	asm volatile("movw %0,%%fs" : : "rm" (seg));
5762306a36Sopenharmony_ci}
5862306a36Sopenharmony_cistatic inline u16 fs(void)
5962306a36Sopenharmony_ci{
6062306a36Sopenharmony_ci	u16 seg;
6162306a36Sopenharmony_ci	asm volatile("movw %%fs,%0" : "=rm" (seg));
6262306a36Sopenharmony_ci	return seg;
6362306a36Sopenharmony_ci}
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_cistatic inline void set_gs(u16 seg)
6662306a36Sopenharmony_ci{
6762306a36Sopenharmony_ci	asm volatile("movw %0,%%gs" : : "rm" (seg));
6862306a36Sopenharmony_ci}
6962306a36Sopenharmony_cistatic inline u16 gs(void)
7062306a36Sopenharmony_ci{
7162306a36Sopenharmony_ci	u16 seg;
7262306a36Sopenharmony_ci	asm volatile("movw %%gs,%0" : "=rm" (seg));
7362306a36Sopenharmony_ci	return seg;
7462306a36Sopenharmony_ci}
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_citypedef unsigned int addr_t;
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_cistatic inline u8 rdfs8(addr_t addr)
7962306a36Sopenharmony_ci{
8062306a36Sopenharmony_ci	u8 *ptr = (u8 *)absolute_pointer(addr);
8162306a36Sopenharmony_ci	u8 v;
8262306a36Sopenharmony_ci	asm volatile("movb %%fs:%1,%0" : "=q" (v) : "m" (*ptr));
8362306a36Sopenharmony_ci	return v;
8462306a36Sopenharmony_ci}
8562306a36Sopenharmony_cistatic inline u16 rdfs16(addr_t addr)
8662306a36Sopenharmony_ci{
8762306a36Sopenharmony_ci	u16 *ptr = (u16 *)absolute_pointer(addr);
8862306a36Sopenharmony_ci	u16 v;
8962306a36Sopenharmony_ci	asm volatile("movw %%fs:%1,%0" : "=r" (v) : "m" (*ptr));
9062306a36Sopenharmony_ci	return v;
9162306a36Sopenharmony_ci}
9262306a36Sopenharmony_cistatic inline u32 rdfs32(addr_t addr)
9362306a36Sopenharmony_ci{
9462306a36Sopenharmony_ci	u32 *ptr = (u32 *)absolute_pointer(addr);
9562306a36Sopenharmony_ci	u32 v;
9662306a36Sopenharmony_ci	asm volatile("movl %%fs:%1,%0" : "=r" (v) : "m" (*ptr));
9762306a36Sopenharmony_ci	return v;
9862306a36Sopenharmony_ci}
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_cistatic inline void wrfs8(u8 v, addr_t addr)
10162306a36Sopenharmony_ci{
10262306a36Sopenharmony_ci	u8 *ptr = (u8 *)absolute_pointer(addr);
10362306a36Sopenharmony_ci	asm volatile("movb %1,%%fs:%0" : "+m" (*ptr) : "qi" (v));
10462306a36Sopenharmony_ci}
10562306a36Sopenharmony_cistatic inline void wrfs16(u16 v, addr_t addr)
10662306a36Sopenharmony_ci{
10762306a36Sopenharmony_ci	u16 *ptr = (u16 *)absolute_pointer(addr);
10862306a36Sopenharmony_ci	asm volatile("movw %1,%%fs:%0" : "+m" (*ptr) : "ri" (v));
10962306a36Sopenharmony_ci}
11062306a36Sopenharmony_cistatic inline void wrfs32(u32 v, addr_t addr)
11162306a36Sopenharmony_ci{
11262306a36Sopenharmony_ci	u32 *ptr = (u32 *)absolute_pointer(addr);
11362306a36Sopenharmony_ci	asm volatile("movl %1,%%fs:%0" : "+m" (*ptr) : "ri" (v));
11462306a36Sopenharmony_ci}
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_cistatic inline u8 rdgs8(addr_t addr)
11762306a36Sopenharmony_ci{
11862306a36Sopenharmony_ci	u8 *ptr = (u8 *)absolute_pointer(addr);
11962306a36Sopenharmony_ci	u8 v;
12062306a36Sopenharmony_ci	asm volatile("movb %%gs:%1,%0" : "=q" (v) : "m" (*ptr));
12162306a36Sopenharmony_ci	return v;
12262306a36Sopenharmony_ci}
12362306a36Sopenharmony_cistatic inline u16 rdgs16(addr_t addr)
12462306a36Sopenharmony_ci{
12562306a36Sopenharmony_ci	u16 *ptr = (u16 *)absolute_pointer(addr);
12662306a36Sopenharmony_ci	u16 v;
12762306a36Sopenharmony_ci	asm volatile("movw %%gs:%1,%0" : "=r" (v) : "m" (*ptr));
12862306a36Sopenharmony_ci	return v;
12962306a36Sopenharmony_ci}
13062306a36Sopenharmony_cistatic inline u32 rdgs32(addr_t addr)
13162306a36Sopenharmony_ci{
13262306a36Sopenharmony_ci	u32 *ptr = (u32 *)absolute_pointer(addr);
13362306a36Sopenharmony_ci	u32 v;
13462306a36Sopenharmony_ci	asm volatile("movl %%gs:%1,%0" : "=r" (v) : "m" (*ptr));
13562306a36Sopenharmony_ci	return v;
13662306a36Sopenharmony_ci}
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_cistatic inline void wrgs8(u8 v, addr_t addr)
13962306a36Sopenharmony_ci{
14062306a36Sopenharmony_ci	u8 *ptr = (u8 *)absolute_pointer(addr);
14162306a36Sopenharmony_ci	asm volatile("movb %1,%%gs:%0" : "+m" (*ptr) : "qi" (v));
14262306a36Sopenharmony_ci}
14362306a36Sopenharmony_cistatic inline void wrgs16(u16 v, addr_t addr)
14462306a36Sopenharmony_ci{
14562306a36Sopenharmony_ci	u16 *ptr = (u16 *)absolute_pointer(addr);
14662306a36Sopenharmony_ci	asm volatile("movw %1,%%gs:%0" : "+m" (*ptr) : "ri" (v));
14762306a36Sopenharmony_ci}
14862306a36Sopenharmony_cistatic inline void wrgs32(u32 v, addr_t addr)
14962306a36Sopenharmony_ci{
15062306a36Sopenharmony_ci	u32 *ptr = (u32 *)absolute_pointer(addr);
15162306a36Sopenharmony_ci	asm volatile("movl %1,%%gs:%0" : "+m" (*ptr) : "ri" (v));
15262306a36Sopenharmony_ci}
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci/* Note: these only return true/false, not a signed return value! */
15562306a36Sopenharmony_cistatic inline bool memcmp_fs(const void *s1, addr_t s2, size_t len)
15662306a36Sopenharmony_ci{
15762306a36Sopenharmony_ci	bool diff;
15862306a36Sopenharmony_ci	asm volatile("fs; repe; cmpsb" CC_SET(nz)
15962306a36Sopenharmony_ci		     : CC_OUT(nz) (diff), "+D" (s1), "+S" (s2), "+c" (len));
16062306a36Sopenharmony_ci	return diff;
16162306a36Sopenharmony_ci}
16262306a36Sopenharmony_cistatic inline bool memcmp_gs(const void *s1, addr_t s2, size_t len)
16362306a36Sopenharmony_ci{
16462306a36Sopenharmony_ci	bool diff;
16562306a36Sopenharmony_ci	asm volatile("gs; repe; cmpsb" CC_SET(nz)
16662306a36Sopenharmony_ci		     : CC_OUT(nz) (diff), "+D" (s1), "+S" (s2), "+c" (len));
16762306a36Sopenharmony_ci	return diff;
16862306a36Sopenharmony_ci}
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci/* Heap -- available for dynamic lists. */
17162306a36Sopenharmony_ciextern char _end[];
17262306a36Sopenharmony_ciextern char *HEAP;
17362306a36Sopenharmony_ciextern char *heap_end;
17462306a36Sopenharmony_ci#define RESET_HEAP() ((void *)( HEAP = _end ))
17562306a36Sopenharmony_cistatic inline char *__get_heap(size_t s, size_t a, size_t n)
17662306a36Sopenharmony_ci{
17762306a36Sopenharmony_ci	char *tmp;
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci	HEAP = (char *)(((size_t)HEAP+(a-1)) & ~(a-1));
18062306a36Sopenharmony_ci	tmp = HEAP;
18162306a36Sopenharmony_ci	HEAP += s*n;
18262306a36Sopenharmony_ci	return tmp;
18362306a36Sopenharmony_ci}
18462306a36Sopenharmony_ci#define GET_HEAP(type, n) \
18562306a36Sopenharmony_ci	((type *)__get_heap(sizeof(type),__alignof__(type),(n)))
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_cistatic inline bool heap_free(size_t n)
18862306a36Sopenharmony_ci{
18962306a36Sopenharmony_ci	return (int)(heap_end-HEAP) >= (int)n;
19062306a36Sopenharmony_ci}
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ci/* copy.S */
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_civoid copy_to_fs(addr_t dst, void *src, size_t len);
19562306a36Sopenharmony_civoid *copy_from_fs(void *dst, addr_t src, size_t len);
19662306a36Sopenharmony_civoid copy_to_gs(addr_t dst, void *src, size_t len);
19762306a36Sopenharmony_civoid *copy_from_gs(void *dst, addr_t src, size_t len);
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci/* a20.c */
20062306a36Sopenharmony_ciint enable_a20(void);
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci/* apm.c */
20362306a36Sopenharmony_ciint query_apm_bios(void);
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci/* bioscall.c */
20662306a36Sopenharmony_cistruct biosregs {
20762306a36Sopenharmony_ci	union {
20862306a36Sopenharmony_ci		struct {
20962306a36Sopenharmony_ci			u32 edi;
21062306a36Sopenharmony_ci			u32 esi;
21162306a36Sopenharmony_ci			u32 ebp;
21262306a36Sopenharmony_ci			u32 _esp;
21362306a36Sopenharmony_ci			u32 ebx;
21462306a36Sopenharmony_ci			u32 edx;
21562306a36Sopenharmony_ci			u32 ecx;
21662306a36Sopenharmony_ci			u32 eax;
21762306a36Sopenharmony_ci			u32 _fsgs;
21862306a36Sopenharmony_ci			u32 _dses;
21962306a36Sopenharmony_ci			u32 eflags;
22062306a36Sopenharmony_ci		};
22162306a36Sopenharmony_ci		struct {
22262306a36Sopenharmony_ci			u16 di, hdi;
22362306a36Sopenharmony_ci			u16 si, hsi;
22462306a36Sopenharmony_ci			u16 bp, hbp;
22562306a36Sopenharmony_ci			u16 _sp, _hsp;
22662306a36Sopenharmony_ci			u16 bx, hbx;
22762306a36Sopenharmony_ci			u16 dx, hdx;
22862306a36Sopenharmony_ci			u16 cx, hcx;
22962306a36Sopenharmony_ci			u16 ax, hax;
23062306a36Sopenharmony_ci			u16 gs, fs;
23162306a36Sopenharmony_ci			u16 es, ds;
23262306a36Sopenharmony_ci			u16 flags, hflags;
23362306a36Sopenharmony_ci		};
23462306a36Sopenharmony_ci		struct {
23562306a36Sopenharmony_ci			u8 dil, dih, edi2, edi3;
23662306a36Sopenharmony_ci			u8 sil, sih, esi2, esi3;
23762306a36Sopenharmony_ci			u8 bpl, bph, ebp2, ebp3;
23862306a36Sopenharmony_ci			u8 _spl, _sph, _esp2, _esp3;
23962306a36Sopenharmony_ci			u8 bl, bh, ebx2, ebx3;
24062306a36Sopenharmony_ci			u8 dl, dh, edx2, edx3;
24162306a36Sopenharmony_ci			u8 cl, ch, ecx2, ecx3;
24262306a36Sopenharmony_ci			u8 al, ah, eax2, eax3;
24362306a36Sopenharmony_ci		};
24462306a36Sopenharmony_ci	};
24562306a36Sopenharmony_ci};
24662306a36Sopenharmony_civoid intcall(u8 int_no, const struct biosregs *ireg, struct biosregs *oreg);
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci/* cmdline.c */
24962306a36Sopenharmony_ciint __cmdline_find_option(unsigned long cmdline_ptr, const char *option, char *buffer, int bufsize);
25062306a36Sopenharmony_ciint __cmdline_find_option_bool(unsigned long cmdline_ptr, const char *option);
25162306a36Sopenharmony_cistatic inline int cmdline_find_option(const char *option, char *buffer, int bufsize)
25262306a36Sopenharmony_ci{
25362306a36Sopenharmony_ci	unsigned long cmd_line_ptr = boot_params.hdr.cmd_line_ptr;
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci	if (cmd_line_ptr >= 0x100000)
25662306a36Sopenharmony_ci		return -1;      /* inaccessible */
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci	return __cmdline_find_option(cmd_line_ptr, option, buffer, bufsize);
25962306a36Sopenharmony_ci}
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_cistatic inline int cmdline_find_option_bool(const char *option)
26262306a36Sopenharmony_ci{
26362306a36Sopenharmony_ci	unsigned long cmd_line_ptr = boot_params.hdr.cmd_line_ptr;
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci	if (cmd_line_ptr >= 0x100000)
26662306a36Sopenharmony_ci		return -1;      /* inaccessible */
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci	return __cmdline_find_option_bool(cmd_line_ptr, option);
26962306a36Sopenharmony_ci}
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_ci/* cpu.c, cpucheck.c */
27262306a36Sopenharmony_ciint check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
27362306a36Sopenharmony_ciint check_knl_erratum(void);
27462306a36Sopenharmony_ciint validate_cpu(void);
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci/* early_serial_console.c */
27762306a36Sopenharmony_ciextern int early_serial_base;
27862306a36Sopenharmony_civoid console_init(void);
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci/* edd.c */
28162306a36Sopenharmony_civoid query_edd(void);
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci/* header.S */
28462306a36Sopenharmony_civoid __attribute__((noreturn)) die(void);
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci/* memory.c */
28762306a36Sopenharmony_civoid detect_memory(void);
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci/* pm.c */
29062306a36Sopenharmony_civoid __attribute__((noreturn)) go_to_protected_mode(void);
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_ci/* pmjump.S */
29362306a36Sopenharmony_civoid __attribute__((noreturn))
29462306a36Sopenharmony_ci	protected_mode_jump(u32 entrypoint, u32 bootparams);
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci/* printf.c */
29762306a36Sopenharmony_ciint sprintf(char *buf, const char *fmt, ...);
29862306a36Sopenharmony_ciint vsprintf(char *buf, const char *fmt, va_list args);
29962306a36Sopenharmony_ciint printf(const char *fmt, ...);
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ci/* regs.c */
30262306a36Sopenharmony_civoid initregs(struct biosregs *regs);
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci/* string.c */
30562306a36Sopenharmony_ciint strcmp(const char *str1, const char *str2);
30662306a36Sopenharmony_ciint strncmp(const char *cs, const char *ct, size_t count);
30762306a36Sopenharmony_cisize_t strnlen(const char *s, size_t maxlen);
30862306a36Sopenharmony_ciunsigned int atou(const char *s);
30962306a36Sopenharmony_ciunsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base);
31062306a36Sopenharmony_cisize_t strlen(const char *s);
31162306a36Sopenharmony_cichar *strchr(const char *s, int c);
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci/* tty.c */
31462306a36Sopenharmony_civoid puts(const char *);
31562306a36Sopenharmony_civoid putchar(int);
31662306a36Sopenharmony_ciint getchar(void);
31762306a36Sopenharmony_civoid kbd_flush(void);
31862306a36Sopenharmony_ciint getchar_timeout(void);
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci/* video.c */
32162306a36Sopenharmony_civoid set_video(void);
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_ci/* video-mode.c */
32462306a36Sopenharmony_ciint set_mode(u16 mode);
32562306a36Sopenharmony_ciint mode_defined(u16 mode);
32662306a36Sopenharmony_civoid probe_cards(int unsafe);
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci/* video-vesa.c */
32962306a36Sopenharmony_civoid vesa_store_edid(void);
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci#endif /* __ASSEMBLY__ */
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci#endif /* BOOT_BOOT_H */
334