summaryrefslogtreecommitdiffhomepage
path: root/src/coreboot-pci-tree.c
blob: b39c024773f16ee95f740e6cd0ee615d3ed4891b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/* -------------------------------------------

	Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.

------------------------------------------- */

/**
 * @file coreboot-pci-tree.c
 * @author Amlal EL Mahrouss (amlal@nekernel.org)
 * @brief PCI tree implementation.
 * @version 0.1
 * @date 2024-01-22
 *
 * @copyright Copyright (c) 2024 Amlal EL Mahrouss
 *
 */

#include <lib/pci-tree.h>
#include <lib/string.h>

/// BUGS: 0

/// Standard Root table (Mahrouss Table)
#define CB_PCI_ROOT_NAME "/pci-tree/@/"

static struct hw_cb_pci_tree* cb_base_tree	 = nil;
static struct hw_cb_pci_tree* cb_latest_tree = nil;
static struct hw_cb_pci_tree* cb_last_tree	 = nil;

/// \brief Init the PCI device tree structure.
/// \return if it already exists -> false
/// Otherwise true.
boolean cb_pci_init_tree(void)
{
	cb_base_tree = (struct hw_cb_pci_tree*)(CB_PCI_TREE_BASE);

	// huh? anyway let's ignore it then.
	if (cb_base_tree->d_magic != CB_PCI_DEV_MAGIC)
	{
		cb_base_tree->d_magic = CB_PCI_DEV_MAGIC;

		memncpy(cb_base_tree->d_name, CB_PCI_ROOT_NAME, strlen(CB_PCI_ROOT_NAME));

		cb_base_tree->d_next_sibling = 0;
		cb_base_tree->d_off_props	 = 0;
		cb_base_tree->d_sz_struct	 = 0;
		cb_base_tree->d_sz_props	 = 0;
		cb_base_tree->d_off_struct	 = 0;
		cb_base_tree->d_version		 = CB_PCI_VERSION;

		cb_base_tree->d_next_sibling =
			(cb_pci_num_t)(cb_base_tree + sizeof(struct hw_cb_pci_tree));
		cb_base_tree->d_first_node = (cb_pci_num_t)cb_base_tree;

		cb_put_string(">> Append root device: " CB_PCI_ROOT_NAME "\r\n");
	}

	cb_latest_tree = cb_base_tree;

	return yes;
}

/// \brief Adds a new device to the tree.
/// \param name the device name.
/// \param struct_ptr the struct containing the device.
/// \param struct_sz the structure size.
boolean cb_pci_append_tree(const caddr_t name, cb_pci_num_t struct_ptr, cb_pci_num_t struct_sz)
{
	if (!name || *name == 0 || cb_latest_tree == nil)
		return no;

	struct hw_cb_pci_tree* cb_pci_tree = (struct hw_cb_pci_tree*)(cb_latest_tree);

	while (cb_pci_tree->d_magic == CB_PCI_DEV_MAGIC)
	{
		if (strcmp(cb_pci_tree->d_name, name) == 0)
			return no;

		cb_pci_tree =
			(struct hw_cb_pci_tree*)(cb_pci_tree +
									 sizeof(struct hw_cb_pci_tree));
	}

	cb_pci_tree->d_magic = CB_PCI_DEV_MAGIC;

	memncpy(cb_pci_tree->d_name, name, strlen(name));

	cb_pci_tree->d_off_struct = struct_ptr;
	cb_pci_tree->d_sz_struct  = struct_sz;
	cb_pci_tree->d_off_props  = 0;
	cb_pci_tree->d_sz_props	  = 0;
	cb_pci_tree->d_version	  = CB_PCI_VERSION;

	cb_pci_tree->d_next_sibling =
		(cb_pci_num_t)(cb_pci_tree + sizeof(struct hw_cb_pci_tree));
	cb_pci_tree->d_first_node = (cb_pci_num_t)cb_latest_tree;

	cb_latest_tree = cb_pci_tree;
	cb_last_tree   = cb_pci_tree;

	cb_put_string(">> Append device: ");
	cb_put_string(name);
	cb_put_string("\r\n");

	return yes;
}