1 /*
2  * Copyright (c) 2023 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 
9 #define DATA_SIZE_K(n)     (n * 1024u)
10 #define RSDP_SIGNATURE     ((uint64_t)0x2052545020445352)
11 #define EBDA_ADD           (0x040e)
12 #define BIOS_RODATA_ADD    (0xe0000)
13 #define BIOS_EXT_DATA_LOW  (0x80000UL)
14 #define BIOS_EXT_DATA_HIGH (0x100000UL)
15 
bios_search_rsdp_buff(uintptr_t search_phy_add,uint32_t search_length)16 static uintptr_t bios_search_rsdp_buff(uintptr_t search_phy_add, uint32_t search_length)
17 {
18 	uint64_t *search_buff;
19 
20 	z_phys_map((uint8_t **)&search_buff, search_phy_add, search_length, 0);
21 	if (!search_buff) {
22 		return 0;
23 	}
24 
25 	for (int i = 0; i < search_length / 8u; i++) {
26 		if (search_buff[i] == RSDP_SIGNATURE) {
27 			z_phys_unmap((uint8_t *)search_buff, search_length);
28 			return (search_phy_add + (i * 8u));
29 		}
30 	}
31 	z_phys_unmap((uint8_t *)search_buff, search_length);
32 
33 	return 0;
34 }
35 
bios_acpi_rsdp_get(void)36 void *bios_acpi_rsdp_get(void)
37 {
38 	uint8_t *bios_ext_data, *zero_page_base;
39 	uintptr_t search_phy_add, rsdp_phy_add;
40 
41 	z_phys_map(&zero_page_base, 0, DATA_SIZE_K(4u), 0);
42 	bios_ext_data = EBDA_ADD + zero_page_base;
43 	search_phy_add = (uintptr_t)((*(uint16_t *)bios_ext_data) << 4u);
44 	z_phys_unmap(zero_page_base, DATA_SIZE_K(4u));
45 
46 	if ((search_phy_add >= BIOS_EXT_DATA_LOW) && (search_phy_add < BIOS_EXT_DATA_HIGH)) {
47 		rsdp_phy_add = bios_search_rsdp_buff(search_phy_add, DATA_SIZE_K(1u));
48 		if (rsdp_phy_add) {
49 			return (void *)rsdp_phy_add;
50 		}
51 	}
52 	return (void *)bios_search_rsdp_buff(BIOS_RODATA_ADD, DATA_SIZE_K(128u));
53 }
54