Files
pepperOS/src/mem/misc/utils.c

122 lines
2.7 KiB
C

#include <stddef.h>
#include <stdint.h>
#include <limine.h>
#include "kernel.h"
#include "string/string.h"
// We won't be linked to standard library, but still need the basic mem* functions
// so everything goes allright with the compiler
// We use the "restrict" keyword on pointers so that the compiler knows it can
// do more optimization on them (and as it's a much used function, it's good to
// be able to do that)
void* memcpy(void* restrict dest, const void* restrict src, size_t n)
{
uint8_t* restrict pdest = (uint8_t* restrict)dest;
const uint8_t* restrict psrc = (const uint8_t* restrict)src;
for (size_t i=0; i<n; i++)
{
pdest[i] = psrc[i];
}
return dest;
}
void* memset(void* s, int c, size_t n)
{
uint8_t* p = (uint8_t*)s;
for (size_t i=0; i<n; i++)
{
p[i] = (uint8_t)c;
}
return s;
}
void* memmove(void *dest, const void* src, size_t n)
{
uint8_t* pdest = (uint8_t*)dest;
const uint8_t* psrc = (uint8_t*)src;
if (src > dest)
{
for (size_t i=0; i<n; i++)
{
pdest[i] = psrc[i];
}
} else if (src < dest)
{
for (size_t i=n; i>0; i--)
{
pdest[i-1] = psrc[i-1];
}
}
return dest;
}
int memcmp(const void* s1, const void* s2, size_t n)
{
const uint8_t* p1 = (const uint8_t*)s1;
const uint8_t* p2 = (const uint8_t*)s2;
for (size_t i=0; i<n; i++)
{
if (p1[i] != p2[i])
{
return p1[i] < p2[i] ? -1 : 1;
}
}
return 0;
}
// Display the memmap so we see how the memory is laid out at handoff
void memmap_display(struct limine_memmap_response* response)
{
DEBUG("Got memory map from Limine: revision %u, %u entries", response->revision, response->entry_count);
for (size_t i=0; i<response->entry_count; i++)
{
struct limine_memmap_entry* entry = response->entries[i];
char type[32] = {0};
switch(entry->type)
{
case LIMINE_MEMMAP_USABLE:
strcpy(type, "USABLE");
break;
case LIMINE_MEMMAP_RESERVED:
strcpy(type, "RESERVED");
break;
case LIMINE_MEMMAP_ACPI_RECLAIMABLE:
strcpy(type, "ACPI_RECLAIMABLE");
break;
case LIMINE_MEMMAP_ACPI_NVS:
strcpy(type, "ACPI_NVS");
break;
case LIMINE_MEMMAP_BAD_MEMORY:
strcpy(type, "BAD_MEMORY");
break;
case LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE:
strcpy(type, "BOOTLOADER_RECLAIMABLE");
break;
case LIMINE_MEMMAP_KERNEL_AND_MODULES:
strcpy(type, "KERNEL_AND_MODULES");
break;
case LIMINE_MEMMAP_FRAMEBUFFER:
strcpy(type, "FRAMEBUFFER");
break;
default:
strcpy(type, "UNKNOWN");
break;
}
DEBUG("entry %02u: [0x%016x | %016u bytes] - %s", i, entry->base, entry->length, type);
}
}
// Display the HHDM
void hhdm_display(struct limine_hhdm_response* hhdm)
{
DEBUG("Got HHDM revision=%u offset=0x%p", hhdm->revision, hhdm->offset);
}