summaryrefslogtreecommitdiffhomepage
path: root/src/neboot-pci-tree.c
blob: 6c2d0ccaee7b03a23f5107a3a3744b96a9609b2e (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
// Copyright 2024-2025, Amlal El Mahrouss (amlal@nekernel.org)
// Distributed under the Apache Software License, Version 2.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.apache.org/licenses/LICENSE-2.0)
// Official repository: https://github.com/nekernel-org/neboot

/**
 * @file neboot-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 <include/pci-tree.h>
#include <include/string.h>

/// BUGS: 0

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

static struct hw_nb_pci_tree* cb_base_tree   = nil;
static struct hw_nb_pci_tree* cb_latest_tree = nil;
static struct hw_nb_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_nb_pci_tree*) (NB_PCI_TREE_BASE);

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

    memncpy(cb_base_tree->d_name, NB_PCI_ROOT_NAME, strlen(NB_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      = NB_PCI_VERSION;

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

    cb_put_string(">> Append root device: " NB_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_nb_pci_tree* cb_pci_tree = (struct hw_nb_pci_tree*) (cb_latest_tree);

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

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

  cb_pci_tree->d_magic = NB_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    = NB_PCI_VERSION;

  cb_pci_tree->d_next_sibling = (cb_pci_num_t) (cb_pci_tree + sizeof(struct hw_nb_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;
}