# DevS querying

## Introduction

The Device System provides a central way to query various kernel subsystems. It is defined in `shelter/lib/include/devs/devs.h` and implemented in `shelter/lib/src/devs/devs.c`.

## Entry point

All DevS related API call goes through a standard entry point:
``` C
sh_devs_query(char *path,sh_devs_RESULT *result)
```

The result is stored inside `result`, which is a structure like this:
``` C
typedef struct {
  enum sh_devs_RESULT_TYPE type;
  sh_uint64 value;
} sh_devs_RESULT;
```

There are severals returned types:
- `SH_DEVS_VALUE`: a 64 bits value
- `SH_DEVS_BOOL`: a boolean stored inside `value` by casting the `sh_bool` to `sh_uint64`
- `SH_DEVS_LAPIC`: `value` should be casted to `sh_lapic_DEVICE*`, which points directly to a LAPIC device structure
- `SH_DEVS_IOAPIC`: `value` should be casted to `sh_ioapic_DEVICE*`, which points directly to a IOAPIC device structure

Each endpoint has a specific syntax, but here are the common syntax elements:
- each path starts with the `$` sign
- each subsystem has its own prefix

Unless you are querying for a pointer (in this case, you can modify the value inside the pointed structure), you can't write anything in the DevS endpoints.

## Endpoint categories

All the kernel subsystems that expose datas through the DevS provide a function to parse the rest of the path without the subsystem prefix once `sh_devs_query()` dispatched the query.

These functions aren't documented in the documentation of these subsystems and shouldn't be called directly.

### LAPIC endpoints

Function:
``` C
sh_lapic_devs_query(char *sub_path,sh_devs_RESULT *result)
```

Prefix: `$apic/lapic`

Endpoints:

Path with syntax | Returned type | Description
-----------------|---------------|------------
`$apic/lapic/by-apic-id/<id>` | `SH_DEVS_LAPIC` | Return the struct of the LAPIC device correspoding to the provided LAPIC id. **Can return `SH_NULLPTR` with a success due to sparses id**
`$apic/lapic/by-acpi-id/<id>` | `SH_DEVS_LAPIC` | Return the struct of the LAPIC device correspoding to the provided ACPI processor id. **Can return `SH_NULLPTR` with a success due to sparses id**
`$apic/lapic/count` | `SH_DEVS_VALUE` | Return the number of LAPIC devices registered
`$apic/lapic/timer-frequency` | `SH_DEVS_VALUE` | Return the estimated frequency of the LAPIC timer
`$apic/lapic/max-apic-id` | `SH_DEVS_VALUE` | Return the biggest LAPIC id among all registered LAPIC devices
`$apic/lapic/max-acpi-id` | `SH_DEVS_VALUE` | Return the biggest ACPI processor id among all registered LAPIC devices
`$apic/lapic/base-address` | `SH_DEVS_VALUE` | Return the physical address of the memory mapped pages for LAPICs
`$apic/lapic/this-cpu-lapic` | `SH_DEVS_LAPIC` | Return the struct of the LAPIC device corresponding to this CPU

### IOAPIC endpoints

Function:
``` C
sh_ioapic_devs_query(char *sub_path,sh_devs_RESULT *result)
```

Prefix: `$apic/ioapic`

Endpoints:

Path with syntax | Returned type | Description
-----------------|---------------|------------
`$apic/ioapic/by-ioapic-id/<id>` | `SH_DEVS_ioAPIC` | Return the struct of the IOAPIC device correspoding to the provided IOAPIC id. **Can return `SH_NULLPTR` with a success due to sparses id**
`$apic/lapic/by-gsi/<gsi>` | `SH_DEVS_IOAPIC` | Return the struct of the IOAPIC device that manages the corresponding GSI. **Can return `SH_NULLPTR` with a success due to sparses GSI**
`$apic/lapic/count` | `SH_DEVS_VALUE` | Return the number of IOAPIC devices registered
`$apic/lapic/max-ioapic-id` | `SH_DEVS_VALUE` | Return the biggest IOAPIC id among all registered IOAPIC devices

### TSC endpoints

Function:
``` C
sh_tsc_devs_query(char *sub_path,sh_devs_RESULT *result)
```

Prefix: `$tsc`

Endpoints:

Path with syntax | Returned type | Description
-----------------|---------------|------------
`$tsc/kernel-init-tsc` | `SH_DEVS_VALUE` | Return the TSC value saved at the start of the kernel C entry point, before AP bootstrap
`$tsc/cpu-freq` | `SH_DEVS_VALUE` | Return the CPU frequency, either estimated or provided by CPU ID
`$tsc/is-cpu-freq-provided` | `SH_DEVS_BOOL` | Return `SH_TRUE` if CPU frequency is provided by CPU ID, `SH_FALSE` if CPU frequency is estimated

### Kernel config endpoints

Function:
``` C
sh_conf_devs_query(char *sub_path,sh_devs_RESULT *result)
```

Prefix: `$kernel/conf`

Endpoints:

Path with syntax | Returned type | Description
-----------------|---------------|------------
`$kernel/conf/log-level` | `SH_DEVS_VALUE` | Return the log level of the kernel
`$kernel/conf/test-benchmark` | `SH_DEVS_BOOL` | Return the test-benchmark state, `SH_TRUE` if enabled
`$kernel/conf/bench-iterations` | `SH_DEVS_VALUE` | Return the amount of iterations used for benchmarking
`$kernel/conf/disable-serial-port` | `SH_DEVS_BOOL` | Return `SH_TRUE` if serial port is disabled, `SH_FALSE` otherwise
`$kernel/conf/kbd-events-queue-capacity` | `SH_DEVS_VALUE` | Return the amount of events a keyboard events queue can store

### Memory subsystem endpoints

Function:
``` C
sh_memory_devs_query(char *sub_path,sh_devs_RESULT *result)
```

Prefix: `$memory`

Endpoints:

Path with syntax | Returned type | Description
-----------------|---------------|------------
`$memory/free-pages` | `SH_DEVS_VALUE` | Return the amount of free pages in the Pez physical plane
`$memory/used-pages` | `SH_DEVS_VALUE` | Return the amount of allocated pages in the Pez physical plane
`$memory/total-pages` | `SH_DEVS_VALUE` | Return the amount of physical pages detected when parsing the memory map
`$memory/installed-pages` | `SH_DEVS_VALUE` | Return the amount of pages detected usable when parsing the memory map. Can be slightly smaller than total pages

### SMP endpoints

Function: integrated to `sh_devs_query()`

Prefix: `$smp`

Path with syntax | Returned type | Description
-----------------|---------------|------------
`$smp/cpu-count` | `SH_DEVS_VALUE` | Return the number of processors
