> ## Documentation Index
> Fetch the complete documentation index at: https://kernel.mvhcloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# HAL API — Hardware Abstraction Layer in MVH Kernel

> MVH Kernel HAL: hal_init, hal_keyboard_read, hal_clock_read, hal_pci_scan, hal_ticks, hal_uptime_seconds, hal_timer_frequency, hal_sleep_ms, hal_reboot.

The Hardware Abstraction Layer (HAL) abstracts platform-specific hardware devices behind a single, uniform interface. Rather than talking directly to the PS/2 controller, the Real-Time Clock (RTC), the PCI bus, or the Programmable Interval Timer (PIT), you call the corresponding `hal_*` function and receive a well-defined result. The HAL bundles keyboard input, wall-clock time, PCI device enumeration, and timer services into one cohesive API that is safe to use from any kernel context after `hal_init` returns.

## Supporting Structures

### `rtc_time_t`

Used by `hal_clock_read` to return the current wall-clock time read from the hardware RTC.

```c theme={null}
typedef struct {
    uint16_t year;
    uint8_t  month;
    uint8_t  day;
    uint8_t  hour;
    uint8_t  minute;
    uint8_t  second;
} rtc_time_t;
```

<ResponseField name="year" type="uint16_t">
  Full four-digit calendar year (e.g., `2025`).
</ResponseField>

<ResponseField name="month" type="uint8_t">
  Month of the year, `1`–`12`.
</ResponseField>

<ResponseField name="day" type="uint8_t">
  Day of the month, `1`–`31`.
</ResponseField>

<ResponseField name="hour" type="uint8_t">
  Hour of the day in 24-hour format, `0`–`23`.
</ResponseField>

<ResponseField name="minute" type="uint8_t">
  Minute of the hour, `0`–`59`.
</ResponseField>

<ResponseField name="second" type="uint8_t">
  Second of the minute, `0`–`59`.
</ResponseField>

***

### `pci_device_t`

Used by `hal_pci_scan` to describe a single PCI device discovered on the bus.

```c theme={null}
typedef struct {
    uint8_t  bus;
    uint8_t  slot;
    uint8_t  function;
    uint8_t  class_code;
    uint8_t  subclass;
    uint16_t vendor;
    uint16_t device;
} pci_device_t;
```

<ResponseField name="bus" type="uint8_t">
  PCI bus number (`0`–`255`) on which the device resides.
</ResponseField>

<ResponseField name="slot" type="uint8_t">
  PCI slot (device) number (`0`–`31`) on the bus.
</ResponseField>

<ResponseField name="function" type="uint8_t">
  PCI function number (`0`–`7`) within the slot.
</ResponseField>

<ResponseField name="class_code" type="uint8_t">
  PCI base class code identifying the broad device category (e.g., `0x01` = Mass Storage, `0x02` = Network).
</ResponseField>

<ResponseField name="subclass" type="uint8_t">
  PCI subclass code that refines the class category.
</ResponseField>

<ResponseField name="vendor" type="uint16_t">
  PCI Vendor ID assigned by the PCI-SIG (e.g., `0x8086` for Intel).
</ResponseField>

<ResponseField name="device" type="uint16_t">
  PCI Device ID assigned by the vendor.
</ResponseField>

***

## Functions

### `hal_init`

Initialize the entire Hardware Abstraction Layer. This function configures the PS/2 keyboard driver, the RTC, the PCI subsystem, and the PIT timer in a single call. You must invoke `hal_init` before using any other `hal_*` function.

```c theme={null}
void hal_init(void);
```

***

### `hal_keyboard_read`

Read one character from the PS/2 keyboard input buffer.

```c theme={null}
char hal_keyboard_read(void);
```

<ResponseField name="return" type="char">
  The ASCII character of the most recently pressed key, or `0` if no key is currently available in the input buffer. This function does not block — poll it in a loop if you need to wait for input.
</ResponseField>

***

### `hal_clock_read`

Read the current date and time from the hardware Real-Time Clock (RTC) and store the result in a caller-supplied `rtc_time_t` struct.

```c theme={null}
void hal_clock_read(rtc_time_t *time);
```

<ParamField path="time" type="rtc_time_t *" required>
  Pointer to an `rtc_time_t` struct that receives the current date and time. All fields are populated on return.
</ParamField>

***

### `hal_pci_scan`

Enumerate all PCI devices on the system bus and populate a caller-supplied array of `pci_device_t` structs.

```c theme={null}
uint32_t hal_pci_scan(pci_device_t *devices, uint32_t capacity);
```

<ParamField path="devices" type="pci_device_t *" required>
  Array of `pci_device_t` to receive discovered device descriptors. Results are written starting at index `0` and truncated to `capacity` if more devices are found.
</ParamField>

<ParamField path="capacity" type="uint32_t" required>
  Number of elements available in the `devices` array.
</ParamField>

<ResponseField name="return" type="uint32_t">
  The number of PCI devices written into `devices`. Never exceeds `capacity`.
</ResponseField>

***

### `hal_ticks`

Return the raw PIT tick counter maintained by the timer interrupt handler.

```c theme={null}
uint64_t hal_ticks(void);
```

<ResponseField name="return" type="uint64_t">
  The cumulative number of PIT ticks since `hal_init` was called. The PIT fires at **100 Hz**, so each tick represents 10 ms. Divide by `hal_timer_frequency()` to obtain elapsed seconds.
</ResponseField>

***

### `hal_uptime_seconds`

Return the number of complete seconds that have elapsed since `hal_init` was called.

```c theme={null}
uint64_t hal_uptime_seconds(void);
```

<ResponseField name="return" type="uint64_t">
  System uptime in whole seconds. Derived from the PIT tick counter; granularity is limited to the timer period (10 ms).
</ResponseField>

***

### `hal_timer_frequency`

Return the configured PIT interrupt frequency.

```c theme={null}
uint32_t hal_timer_frequency(void);
```

<ResponseField name="return" type="uint32_t">
  Timer frequency in Hz. Always `100` in the current release (one tick per 10 ms).
</ResponseField>

***

### `hal_sleep_ms`

Busy-sleep for at least the specified number of milliseconds. The function spins on the PIT tick counter and returns only after the requested delay has elapsed.

```c theme={null}
void hal_sleep_ms(uint64_t milliseconds);
```

<ParamField path="milliseconds" type="uint64_t" required>
  Number of milliseconds to sleep. Because the PIT resolution is 10 ms, actual sleep duration is rounded up to the nearest 10 ms boundary.
</ParamField>

<Note>
  `hal_sleep_ms` is a busy-wait. It consumes CPU cycles for the entire duration and should not be used for long delays in latency-sensitive code paths.
</Note>

***

### `hal_reboot`

Reboot the system immediately. This function does not return.

```c theme={null}
void hal_reboot(void) __attribute__((noreturn));
```

<Warning>
  `hal_reboot` triggers an immediate system reset. Any in-flight VFS or RAMFS data is discarded. Make sure all work is complete before calling this function.
</Warning>

***

## Examples

### Reading the Real-Time Clock

```c theme={null}
#include "mvh/hal.h"

void print_time(void) {
    hal_init();

    rtc_time_t now;
    hal_clock_read(&now);

    /* now.year, now.month, now.day, now.hour, now.minute, now.second */
    (void)now;
}
```

### Scanning the PCI Bus

```c theme={null}
#include "mvh/hal.h"

void enumerate_pci(void) {
    hal_init();

    pci_device_t devices[32];
    uint32_t count = hal_pci_scan(devices, 32);

    for (uint32_t i = 0; i < count; i++) {
        /* devices[i].vendor, devices[i].device,
           devices[i].class_code, devices[i].subclass */
        (void)devices[i];
    }
}
```

### Sleeping for a Fixed Delay

```c theme={null}
#include "mvh/hal.h"

void delayed_init(void) {
    hal_init();

    /* Wait 500 ms before proceeding */
    hal_sleep_ms(500);

    /* Continue with time-sensitive hardware initialization */
}
```
