Compare commits
15 Commits
c9239f6921
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| de191c15df | |||
| e1b8ae10a3 | |||
| fd7889da13 | |||
| e4f47af722 | |||
| 8b4e7395f5 | |||
| b34bfdbf63 | |||
| 336d6e2c52 | |||
| 9fb213cc41 | |||
| bd354fed8c | |||
| a7577d1921 | |||
| d63c88259f | |||
| 37fc085646 | |||
| 353a8465a3 | |||
| 8c650daf69 | |||
| 1bff60c27a |
@@ -5,7 +5,7 @@ their work (or fun! >:3) done while having their machine resources managed clean
|
|||||||
scenes. SPx is architected by a fluffy kitty cat who likes eating bugs and mice and RATS NOM
|
scenes. SPx is architected by a fluffy kitty cat who likes eating bugs and mice and RATS NOM
|
||||||
NOM NOM !!!! This kitty will protect your wittle den, don't worry critter!
|
NOM NOM !!!! This kitty will protect your wittle den, don't worry critter!
|
||||||
|
|
||||||
-- Confidentiality of implementation --
|
-- Open source --
|
||||||
|
|
||||||
This repository and its sources as of Thu Apr 16 is CONFIDENTIAL and PROPRIETARY.
|
This system software has been open sourced, all confidentiality notices have been preserved
|
||||||
Unauthorized distribution or modification is strictly prohibited.
|
for historical purposes.
|
||||||
|
|||||||
+1
-1
@@ -34,7 +34,7 @@ check_deps() {
|
|||||||
#
|
#
|
||||||
get_toolchain() {
|
get_toolchain() {
|
||||||
if [ ! -d var/cc/toolchain ]; then
|
if [ ! -d var/cc/toolchain ]; then
|
||||||
git clone https://git.mirocom.org/Mirocom/mirocom-toolchain --depth=1 var/cc/toolchain
|
git clone https://git.mirocom.org/chloe/mirocom-toolchain --depth=1 var/cc/toolchain
|
||||||
cd var/cc/toolchain
|
cd var/cc/toolchain
|
||||||
tar -xzvf toolchain.tar.gz
|
tar -xzvf toolchain.tar.gz
|
||||||
mv public/* .; rm -rf public/
|
mv public/* .; rm -rf public/
|
||||||
|
|||||||
@@ -9,10 +9,16 @@
|
|||||||
* consent from Mirocom Laboratories.
|
* consent from Mirocom Laboratories.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
#include <sys/status.h>
|
||||||
#include <mu/mmu.h>
|
#include <mu/mmu.h>
|
||||||
#include <mm/vm.h>
|
#include <mm/vm.h>
|
||||||
#include <mm/physmem.h>
|
#include <mm/physmem.h>
|
||||||
|
#include <machine/tlb.h>
|
||||||
|
#include <machine/param.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Page-Table Entry (PTE) flags
|
* Page-Table Entry (PTE) flags
|
||||||
@@ -31,6 +37,154 @@
|
|||||||
#define PTE_GLOBAL BIT(8) /* Global; sticky */
|
#define PTE_GLOBAL BIT(8) /* Global; sticky */
|
||||||
#define PTE_NX BIT(63) /* Execute-disable */
|
#define PTE_NX BIT(63) /* Execute-disable */
|
||||||
|
|
||||||
|
/* 57-bit linear addresses */
|
||||||
|
#define CR4_LA57 BIT(12)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Represents valid pagemap levels
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
PAGELVL_PML1,
|
||||||
|
PAGELVL_PML2,
|
||||||
|
PAGELVL_PML3,
|
||||||
|
PAGELVL_PML4,
|
||||||
|
PAGELVL_PML5
|
||||||
|
} pagelvl_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Obtain page table flags from protection flags
|
||||||
|
*
|
||||||
|
* @prot: Protection flags to extract from
|
||||||
|
*/
|
||||||
|
static size_t
|
||||||
|
mmu_prot_to_pte(int prot)
|
||||||
|
{
|
||||||
|
size_t pte_flags = PTE_P | PTE_NX;
|
||||||
|
|
||||||
|
if (ISSET(prot, PROT_WRITE))
|
||||||
|
pte_flags |= PTE_RW;
|
||||||
|
if (ISSET(prot, PROT_EXEC))
|
||||||
|
pte_flags &= ~PTE_NX;
|
||||||
|
|
||||||
|
return pte_flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Verify if a pagesize is valid
|
||||||
|
*
|
||||||
|
* @ps: Pagesize to verify
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
mmu_ps_valid(pagelvl_t ps)
|
||||||
|
{
|
||||||
|
switch (ps) {
|
||||||
|
case PAGESIZE_4K:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Obtain the top-level in use for the current machine
|
||||||
|
* configuration.
|
||||||
|
*/
|
||||||
|
static inline pagelvl_t
|
||||||
|
mmu_get_level(void)
|
||||||
|
{
|
||||||
|
uint64_t cr4;
|
||||||
|
|
||||||
|
__asmv(
|
||||||
|
"mov %%cr4, %0"
|
||||||
|
: "=r" (cr4)
|
||||||
|
:
|
||||||
|
: "memory"
|
||||||
|
);
|
||||||
|
|
||||||
|
return ISSET(cr4, CR4_LA57)
|
||||||
|
? PAGELVL_PML5
|
||||||
|
: PAGELVL_PML4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function extracts those cute 9 bit segments that
|
||||||
|
* function as indices into pagemap levels.
|
||||||
|
*
|
||||||
|
* @vma: Virtual memory address used as key
|
||||||
|
* @lvl: Level to extract
|
||||||
|
*/
|
||||||
|
static inline size_t
|
||||||
|
mmu_extract_index(uintptr_t vma, pagelvl_t lvl)
|
||||||
|
{
|
||||||
|
switch (lvl) {
|
||||||
|
case PAGELVL_PML1:
|
||||||
|
return (vma >> 12) & 0x1FF;
|
||||||
|
case PAGELVL_PML2:
|
||||||
|
return (vma >> 21) & 0x1FF;
|
||||||
|
case PAGELVL_PML3:
|
||||||
|
return (vma >> 30) & 0x1FF;
|
||||||
|
case PAGELVL_PML4:
|
||||||
|
return (vma >> 39) & 0x1FF;
|
||||||
|
case PAGELVL_PML5:
|
||||||
|
return (vma >> 48) & 0x1FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (size_t)-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extract a pagemap index
|
||||||
|
*
|
||||||
|
* @vfr: Virtual fuck region
|
||||||
|
* @vma: Virtual memory address
|
||||||
|
* @lvl: Pagemap level to extract
|
||||||
|
* @alloc: If true, allocate new entries
|
||||||
|
*/
|
||||||
|
static uint64_t *
|
||||||
|
mmu_extract_level(struct mmu_vfr *vfr, uintptr_t vma, pagelvl_t lvl, bool alloc)
|
||||||
|
{
|
||||||
|
uintptr_t *pmap, pma;
|
||||||
|
void *tmp_p;
|
||||||
|
size_t index;
|
||||||
|
pagelvl_t cur_level;
|
||||||
|
|
||||||
|
if (vfr == NULL || lvl > PAGELVL_PML5) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_level = mmu_get_level();
|
||||||
|
pmap = pma_to_vma((vfr->cr3 & PTE_ADDR_MASK));
|
||||||
|
|
||||||
|
while (cur_level > lvl) {
|
||||||
|
index = mmu_extract_index(vma, cur_level);
|
||||||
|
|
||||||
|
/* Is this entry present? */
|
||||||
|
if (ISSET(pmap[index], PTE_P)) {
|
||||||
|
pmap = pma_to_vma((pmap[index] & PTE_ADDR_MASK));
|
||||||
|
--cur_level;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!alloc) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
pma = mm_physmem_alloc(1);
|
||||||
|
if (pma == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp_p = pma_to_vma(pma);
|
||||||
|
memset(tmp_p, 0, PAGESIZE);
|
||||||
|
pmap[index] = pma | (PTE_P | PTE_RW | PTE_US);
|
||||||
|
|
||||||
|
pmap = tmp_p;
|
||||||
|
--cur_level;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pmap;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
mu_mmu_readvfr(struct mmu_vfr *res)
|
mu_mmu_readvfr(struct mmu_vfr *res)
|
||||||
{
|
{
|
||||||
@@ -89,3 +243,48 @@ mu_mmu_forkvfr(struct mmu_vfr *vfr, struct mmu_vfr *res)
|
|||||||
res->cr3 = dest;
|
res->cr3 = dest;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
mu_mmu_map(struct mmu_vfr *vfr, uintptr_t vma, uintptr_t pma,
|
||||||
|
int prot, pagesize_t ps)
|
||||||
|
{
|
||||||
|
uintptr_t *tbl;
|
||||||
|
size_t index, flags;
|
||||||
|
|
||||||
|
if (vfr == NULL || !mmu_ps_valid(ps)) {
|
||||||
|
return STATUS_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbl = mmu_extract_level(vfr, vma, PAGELVL_PML1, true);
|
||||||
|
if (tbl == NULL) {
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = mmu_extract_index(vma, PAGELVL_PML1);
|
||||||
|
flags = mmu_prot_to_pte(prot);
|
||||||
|
|
||||||
|
tbl[index] = pma | flags;
|
||||||
|
md_tlb_flush(vma);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
mu_mmu_unmap(struct mmu_vfr *vfr, uintptr_t vma, pagesize_t ps)
|
||||||
|
{
|
||||||
|
uintptr_t *tbl;
|
||||||
|
size_t index;
|
||||||
|
|
||||||
|
if (vfr == NULL) {
|
||||||
|
return STATUS_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbl = mmu_extract_level(vfr, vma, PAGELVL_PML1, false);
|
||||||
|
if (tbl == NULL) {
|
||||||
|
return STATUS_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
index = mmu_extract_index(vma, PAGELVL_PML1);
|
||||||
|
tbl[index] = 0;
|
||||||
|
md_tlb_flush(vma);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,160 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2026, Mirocom Laboratories
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The following sources are CONFIDENTIAL and PROPRIETARY
|
||||||
|
* property of Mirocom Laboratories. Unauthorized copying,
|
||||||
|
* use, distribution or modification of this file, in whole
|
||||||
|
* and in part, is strictly prohibited without the prior written
|
||||||
|
* consent from Mirocom Laboratories.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <os/knot.h>
|
||||||
|
#include <lib/printf.h>
|
||||||
|
#include <machine/irqchip.h>
|
||||||
|
#include <io/acpi/acpi.h>
|
||||||
|
#include <io/acpi/tables.h>
|
||||||
|
#include <mm/vm.h>
|
||||||
|
|
||||||
|
#define pr_trace(fmt, ...) \
|
||||||
|
printf("irqchip: " fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
/* Online capable */
|
||||||
|
#define LAPIC_ONLCAP BIT(1)
|
||||||
|
|
||||||
|
/* I/O APIC */
|
||||||
|
static struct irqchip ioapic_list[MAX_IOAPIC];
|
||||||
|
static size_t ioapic_count = 0;
|
||||||
|
|
||||||
|
/* Local APIC */
|
||||||
|
static struct irqchip lapic_list[MAX_LAPIC];
|
||||||
|
static size_t lapic_count = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a Local APIC descriptor
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
irqchip_lapic_append(const struct irqchip *irqchip)
|
||||||
|
{
|
||||||
|
if (lapic_count >= MAX_LAPIC) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lapic_list[lapic_count++] = *irqchip;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add an I/O APIC descriptor
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
irqchip_ioapic_append(const struct irqchip *irqchip)
|
||||||
|
{
|
||||||
|
if (ioapic_count >= MAX_IOAPIC) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ioapic_list[ioapic_count++] = *irqchip;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print information about a Local APIC unit
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
irqchip_print_lapic(struct local_apic *lapic)
|
||||||
|
{
|
||||||
|
static uint16_t log_count = 0;
|
||||||
|
|
||||||
|
if (lapic == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((log_count++) >= 4) {
|
||||||
|
pr_trace("....\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pr_trace("lapic(%d).cpu : %d\n",
|
||||||
|
lapic->apic_id, lapic->processor_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print information about an I/O APIC unit
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
irqchip_print_ioapic(struct ioapic *ioapic)
|
||||||
|
{
|
||||||
|
if (ioapic == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pr_trace("ioapic(%d).gsi_base : %d\n",
|
||||||
|
ioapic->ioapic_id, ioapic->gsi_base);
|
||||||
|
pr_trace("ioapic(%d).mmio : %p\n",
|
||||||
|
ioapic->ioapic_id, ioapic->ioapic_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
md_irqchip_init(void)
|
||||||
|
{
|
||||||
|
struct irqchip chip;
|
||||||
|
struct acpi_madt *madt;
|
||||||
|
struct local_apic *lapic;
|
||||||
|
struct ioapic *ioapic;
|
||||||
|
struct apic_header *hdr;
|
||||||
|
char *cur, *end;
|
||||||
|
|
||||||
|
madt = acpi_query("APIC");
|
||||||
|
if (madt == NULL) {
|
||||||
|
knot("could not query acpi madt table\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
cur = (char *)(madt + 1);
|
||||||
|
end = (char *)madt + madt->hdr.length;
|
||||||
|
|
||||||
|
while (cur < end) {
|
||||||
|
hdr = (struct apic_header *)cur;
|
||||||
|
|
||||||
|
switch (hdr->type) {
|
||||||
|
case APIC_TYPE_LOCAL_APIC:
|
||||||
|
lapic = (struct local_apic *)hdr;
|
||||||
|
irqchip_print_lapic(lapic);
|
||||||
|
|
||||||
|
chip.mmio = pma_to_vma(madt->lapic_addr);
|
||||||
|
chip.apic_id = lapic->apic_id;
|
||||||
|
irqchip_lapic_append(&chip);
|
||||||
|
break;
|
||||||
|
case APIC_TYPE_IO_APIC:
|
||||||
|
ioapic = (struct ioapic *)hdr;
|
||||||
|
irqchip_print_ioapic(ioapic);
|
||||||
|
|
||||||
|
chip.mmio = pma_to_vma(ioapic->ioapic_addr);
|
||||||
|
chip.apic_id = ioapic->ioapic_id;
|
||||||
|
irqchip_lapic_append(&chip);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur += hdr->length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct irqchip *
|
||||||
|
md_ioapic_index(size_t index)
|
||||||
|
{
|
||||||
|
if (index >= ioapic_count) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ioapic_list[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
struct irqchip *
|
||||||
|
md_lapic_index(size_t index)
|
||||||
|
{
|
||||||
|
if (index >= lapic_count) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &lapic_list[index];
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include <os/bpt.h>
|
#include <os/bpt.h>
|
||||||
#include <mm/vm.h>
|
#include <mm/vm.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <machine/irqchip.h> /* shared */
|
||||||
|
|
||||||
#define pr_trace(fmt, ...) \
|
#define pr_trace(fmt, ...) \
|
||||||
printf("acpi: " fmt, ##__VA_ARGS__)
|
printf("acpi: " fmt, ##__VA_ARGS__)
|
||||||
@@ -101,4 +102,6 @@ acpi_init(void)
|
|||||||
root_sdt = pma_to_vma((uintptr_t)rsdp->xsdt_addr);
|
root_sdt = pma_to_vma((uintptr_t)rsdp->xsdt_addr);
|
||||||
root_sdt_entries = (root_sdt->hdr.length - sizeof(root_sdt->hdr)) / 8;
|
root_sdt_entries = (root_sdt->hdr.length - sizeof(root_sdt->hdr)) / 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
md_irqchip_init();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2026, Mirocom Laboratories
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The following sources are CONFIDENTIAL and PROPRIETARY
|
||||||
|
* property of Mirocom Laboratories. Unauthorized copying,
|
||||||
|
* use, distribution or modification of this file, in whole
|
||||||
|
* and in part, is strictly prohibited without the prior written
|
||||||
|
* consent from Mirocom Laboratories.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/units.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <lib/printf.h>
|
||||||
|
#include <mu/mmu.h>
|
||||||
|
#include <mu/param.h>
|
||||||
|
#include <mm/vm.h>
|
||||||
|
|
||||||
|
#define pr_trace(fmt, ...) \
|
||||||
|
printf("vm_map: " fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
/* Used to safely convert pagesize constants */
|
||||||
|
#define GRAN(ps) \
|
||||||
|
((ps) <= PAGESIZE_1G) \
|
||||||
|
? pstab[(ps)] \
|
||||||
|
: pstab[PAGESIZE_4K]
|
||||||
|
|
||||||
|
/* Pagesize constant to length table */
|
||||||
|
static size_t pstab[] = {
|
||||||
|
[PAGESIZE_4K] = 0x1000,
|
||||||
|
[PAGESIZE_2M] = UNIT_MIB * 2,
|
||||||
|
[PAGESIZE_1G] = UNIT_GIB
|
||||||
|
};
|
||||||
|
|
||||||
|
status_t
|
||||||
|
mm_vm_map(struct mmu_vfr *vfr, struct vm_map *mapping, int prot)
|
||||||
|
{
|
||||||
|
size_t len, gran;
|
||||||
|
uintptr_t vma, pma;
|
||||||
|
status_t status;
|
||||||
|
|
||||||
|
if (vfr == NULL || mapping == NULL) {
|
||||||
|
return STATUS_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
gran = GRAN(mapping->ps);
|
||||||
|
vma = ALIGN_DOWN(mapping->vma_base, gran);
|
||||||
|
pma = ALIGN_DOWN(mapping->pma_base, gran);
|
||||||
|
|
||||||
|
len = mapping->length;
|
||||||
|
len = ALIGN_UP(len + (len & (gran - 1)), gran);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < len; i += gran) {
|
||||||
|
status = mu_mmu_map(vfr, vma + i, pma + i, prot, mapping->ps);
|
||||||
|
|
||||||
|
/* Destroy what we created on failure */
|
||||||
|
if (status != STATUS_SUCCESS) {
|
||||||
|
mm_vm_unmap(vfr, mapping);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
mm_vm_unmap(struct mmu_vfr *vfr, struct vm_map *mapping)
|
||||||
|
{
|
||||||
|
size_t gran, len;
|
||||||
|
uintptr_t vma;
|
||||||
|
|
||||||
|
if (vfr == NULL || mapping == NULL) {
|
||||||
|
return STATUS_INVALID_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
gran = GRAN(mapping->ps);
|
||||||
|
vma = ALIGN_DOWN(mapping->vma_base, gran);
|
||||||
|
|
||||||
|
len = mapping->length;
|
||||||
|
len = ALIGN_UP(len + (len & (gran - 1)), gran);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < len; i += gran) {
|
||||||
|
mu_mmu_unmap(vfr, vma + i, mapping->ps);
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2026, Mirocom Laboratories
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The following sources are CONFIDENTIAL and PROPRIETARY
|
||||||
|
* property of Mirocom Laboratories. Unauthorized copying,
|
||||||
|
* use, distribution or modification of this file, in whole
|
||||||
|
* and in part, is strictly prohibited without the prior written
|
||||||
|
* consent from Mirocom Laboratories.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MACHINE_IRQCHIP_H_
|
||||||
|
#define _MACHINE_IRQCHIP_H_ 1
|
||||||
|
|
||||||
|
#include <sys/status.h>
|
||||||
|
|
||||||
|
#define MAX_IOAPIC 8
|
||||||
|
#define MAX_LAPIC 64
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @IRQCHIP_NONE: This IRQ chip has no type
|
||||||
|
* @IRQCHIP_LAPIC: This IRQ chip is a Local APIC
|
||||||
|
* @IRQCHIP_IOAPIC: This IRQ chip is an I/O APIC
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
IRQCHIP_NONE,
|
||||||
|
IRQCHIP_LAPIC,
|
||||||
|
IRQCHIP_IOAPIC
|
||||||
|
} irqchip_type_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Represents a platform interrupt controller
|
||||||
|
* chip
|
||||||
|
*
|
||||||
|
* @type: IRQ chip type
|
||||||
|
* @apic_id: APIC ID
|
||||||
|
* @mmio: Memory mapped I/O address
|
||||||
|
*/
|
||||||
|
struct irqchip {
|
||||||
|
irqchip_type_t type;
|
||||||
|
uint8_t apic_id;
|
||||||
|
void *mmio;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize platform interrupt controller chips
|
||||||
|
*/
|
||||||
|
status_t md_irqchip_init(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Obtain an I/O APIC descriptor by index
|
||||||
|
*
|
||||||
|
* @index: Index of entry to obtain
|
||||||
|
*/
|
||||||
|
struct irqchip *md_ioapic_index(size_t index);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Obtain an Local APIC descriptor by index
|
||||||
|
*
|
||||||
|
* @index: Index of entry to obtain
|
||||||
|
*/
|
||||||
|
struct irqchip *md_lapic_index(size_t index);
|
||||||
|
|
||||||
|
#endif /* !_MACHINE_IRQCHIP_H_ */
|
||||||
@@ -12,18 +12,53 @@
|
|||||||
#ifndef _MM_VM_H_
|
#ifndef _MM_VM_H_
|
||||||
#define _MM_VM_H_ 1
|
#define _MM_VM_H_ 1
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <os/bpt.h>
|
#include <os/bpt.h>
|
||||||
|
#include <mu/mmu.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Represents a virtual memory mapping that can be made
|
||||||
|
*
|
||||||
|
* @ps: Pagesize
|
||||||
|
* @vma_base: Virtual memory base
|
||||||
|
* @pma_base: Physical memory base
|
||||||
|
* @length: Number of bytes to map
|
||||||
|
*
|
||||||
|
* XXX: `pma_base' is unused when unmapping regions
|
||||||
|
*/
|
||||||
|
struct vm_map {
|
||||||
|
pagesize_t ps;
|
||||||
|
uintptr_t vma_base;
|
||||||
|
uintptr_t pma_base;
|
||||||
|
size_t length;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Macros used to convert physical to virtual addresses
|
* Macros used to convert physical to virtual addresses
|
||||||
* and vice versa.
|
* and vice versa.
|
||||||
*/
|
*/
|
||||||
#define pma_to_vma(pma) \
|
#define pma_to_vma(pma) \
|
||||||
PTR_OFFSET((void *)pma, bpt_kload_base())
|
PTR_OFFSET((void *)((uintptr_t)pma), bpt_kload_base())
|
||||||
#define vma_to_pma(vma) \
|
#define vma_to_pma(vma) \
|
||||||
(uintptr_t)PTR_NOFFSET(vma, bpt_kload_base())
|
(uintptr_t)PTR_NOFFSET(vma, bpt_kload_base())
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a virtual memory mapping
|
||||||
|
*
|
||||||
|
* @vfr: Virtual fuck region to map within
|
||||||
|
* @mapping: Mapping to create
|
||||||
|
*/
|
||||||
|
status_t mm_vm_map(struct mmu_vfr *vfr, struct vm_map *mapping, int prot);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Destroy a virtual memory mapping
|
||||||
|
*
|
||||||
|
* @vfr: Virtual fuck region to unmap within
|
||||||
|
* @mapping: Mapping to destroy
|
||||||
|
*/
|
||||||
|
status_t mm_vm_unmap(struct mmu_vfr *vfr, struct vm_map *mapping);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the virtual memory management
|
* Initialize the virtual memory management
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2026, Mirocom Laboratories
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* The following sources are CONFIDENTIAL and PROPRIETARY
|
||||||
|
* property of Mirocom Laboratories. Unauthorized copying,
|
||||||
|
* use, distribution or modification of this file, in whole
|
||||||
|
* and in part, is strictly prohibited without the prior written
|
||||||
|
* consent from Mirocom Laboratories.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MU_MMIO_H_
|
||||||
|
#define _MU_MMIO_H_ 1
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
|
/* Builds mmio_write<n> functions */
|
||||||
|
#define _MMIO_WRITE_BUILDER(NAME, TYPE) \
|
||||||
|
static inline void \
|
||||||
|
mmio_##NAME(TYPE *ptr, TYPE val) \
|
||||||
|
{ \
|
||||||
|
__barrier(); \
|
||||||
|
*(volatile TYPE *)ptr = val; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Builds mmio_read<n> functions */
|
||||||
|
#define _MMIO_READ_BUILDER(NAME, TYPE) \
|
||||||
|
static inline TYPE \
|
||||||
|
mmio_##NAME(TYPE *ptr) \
|
||||||
|
{ \
|
||||||
|
__barrier(); \
|
||||||
|
return *(volatile TYPE *)ptr; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mmio_write<n> */
|
||||||
|
_MMIO_WRITE_BUILDER(write8, uint8_t);
|
||||||
|
_MMIO_WRITE_BUILDER(write16, uint16_t);
|
||||||
|
_MMIO_WRITE_BUILDER(write32, uint32_t);
|
||||||
|
#if __SIZEOF_SIZE_T__ == 8
|
||||||
|
_MMIO_WRITE_BUILDER(write64, uint64_t);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Builds mmio_read<n> functions */
|
||||||
|
_MMIO_READ_BUILDER(read8, uint8_t);
|
||||||
|
_MMIO_READ_BUILDER(read16, uint16_t);
|
||||||
|
_MMIO_READ_BUILDER(read32, uint32_t);
|
||||||
|
#if __SIZEOF_SIZE_T__ == 8
|
||||||
|
_MMIO_READ_BUILDER(read64, uint64_t);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !_MU_MMIO_H_ */
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
#define _MU_MMU_H_ 1
|
#define _MU_MMU_H_ 1
|
||||||
|
|
||||||
#include <sys/status.h>
|
#include <sys/status.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Each running SP1 process is to have a virtual fuck region
|
* Each running SP1 process is to have a virtual fuck region
|
||||||
@@ -21,6 +22,16 @@
|
|||||||
*/
|
*/
|
||||||
#include <machine/vfr.h> /* shared; virtual fuck region~ */
|
#include <machine/vfr.h> /* shared; virtual fuck region~ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Represents valid page sizes that can be used when
|
||||||
|
* creating mappings
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
PAGESIZE_4K,
|
||||||
|
PAGESIZE_2M,
|
||||||
|
PAGESIZE_1G
|
||||||
|
} pagesize_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Obtain the current VFR in-use
|
* Obtain the current VFR in-use
|
||||||
*
|
*
|
||||||
@@ -35,6 +46,35 @@ void mu_mmu_readvfr(struct mmu_vfr *res);
|
|||||||
*/
|
*/
|
||||||
void mu_mmu_writevfr(struct mmu_vfr *vfr);
|
void mu_mmu_writevfr(struct mmu_vfr *vfr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a virtual to physical mapping within a
|
||||||
|
* specific virtual fuck region
|
||||||
|
*
|
||||||
|
* @vfr: Virtual fuck region to map within
|
||||||
|
* @vma: Virtual memory address to map
|
||||||
|
* @pma: Physical memory address to map to
|
||||||
|
* @prot: Protection flags
|
||||||
|
* @pagesize_t: Pagesize to map
|
||||||
|
*/
|
||||||
|
status_t mu_mmu_map(
|
||||||
|
struct mmu_vfr *vfr, uintptr_t vma,
|
||||||
|
uintptr_t pma, int prot,
|
||||||
|
pagesize_t ps
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Destroy a virtual memory mapping in the virtual
|
||||||
|
* fuck region
|
||||||
|
*
|
||||||
|
* @vfr: Virtual fuck region to unmap within
|
||||||
|
* @vma: Virtual memory address to unmap
|
||||||
|
* @ps: Pagesize of address to unmap
|
||||||
|
*/
|
||||||
|
status_t mu_mmu_unmap(
|
||||||
|
struct mmu_vfr *vfr, uintptr_t vma,
|
||||||
|
pagesize_t ps
|
||||||
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fork a VFR and clear out the lower half
|
* Fork a VFR and clear out the lower half
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user