XHCI works on real hardware!
This commit is contained in:
@@ -54,7 +54,7 @@ void* mmap (void* addr, size_t size, int prot, int flags, int fd, size_t off) {
|
||||
|
||||
size = div_align_up (size, PAGE_SIZE);
|
||||
|
||||
physaddr_t p_addr = pmm_alloc (size);
|
||||
uintptr_t p_addr = pmm_alloc (size);
|
||||
|
||||
if (p_addr == PMM_ALLOC_ERR)
|
||||
return (void*)-1;
|
||||
@@ -75,7 +75,7 @@ int munmap (void* addr, size_t length) {
|
||||
|
||||
struct limine_hhdm_response* hhdm = limine_hhdm_request.response;
|
||||
|
||||
physaddr_t p_addr = (uintptr_t)addr - hhdm->offset;
|
||||
uintptr_t p_addr = (uintptr_t)addr - hhdm->offset;
|
||||
|
||||
pmm_free (p_addr, length);
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <limine/limine.h>
|
||||
#include <limine/requests.h>
|
||||
#include <mm/pmm.h>
|
||||
#include <mm/types.h>
|
||||
#include <sync/spin_lock.h>
|
||||
#include <sys/debug.h>
|
||||
#include <sys/mm.h>
|
||||
@@ -43,15 +42,15 @@ void pmm_init (void) {
|
||||
* */
|
||||
|
||||
size_t size = align_down (entry->length, PAGE_SIZE);
|
||||
physaddr_t start = align_up (entry->base, PAGE_SIZE);
|
||||
uintptr_t start = align_up (entry->base, PAGE_SIZE);
|
||||
|
||||
size_t max_pages = (size * 8) / (PAGE_SIZE * 8 + 1);
|
||||
|
||||
size_t bm_nbits = max_pages;
|
||||
size_t bm_size = align_up (bm_nbits, 8) / 8;
|
||||
|
||||
physaddr_t bm_base = start;
|
||||
physaddr_t data_base = align_up (bm_base + bm_size, PAGE_SIZE);
|
||||
uintptr_t bm_base = start;
|
||||
uintptr_t data_base = align_up (bm_base + bm_size, PAGE_SIZE);
|
||||
|
||||
if (bm_base + bm_size >= start + size)
|
||||
continue;
|
||||
@@ -99,7 +98,23 @@ static size_t pmm_find_free_space (struct pmm_region* pmm_region, size_t nblks)
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
physaddr_t pmm_alloc (size_t nblks) {
|
||||
static size_t pmm_find_free_space_aligned (struct pmm_region* pmm_region, size_t nblks,
|
||||
size_t align_pages) {
|
||||
if (align_pages == 0)
|
||||
align_pages = 1;
|
||||
|
||||
for (size_t bit = 0; bit < pmm_region->bm.nbits; bit += align_pages) {
|
||||
if (bm_test_region (&pmm_region->bm, bit, nblks)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return bit;
|
||||
}
|
||||
|
||||
return (size_t)-1;
|
||||
}
|
||||
|
||||
uintptr_t pmm_alloc (size_t nblks) {
|
||||
uint64_t fpr;
|
||||
|
||||
for (size_t region = 0; region < PMM_REGIONS_MAX; region++) {
|
||||
@@ -129,11 +144,41 @@ physaddr_t pmm_alloc (size_t nblks) {
|
||||
return PMM_ALLOC_ERR;
|
||||
}
|
||||
|
||||
void pmm_free (physaddr_t p_addr, size_t nblks) {
|
||||
uintptr_t pmm_alloc_aligned (size_t nblks, size_t align_pages) {
|
||||
uint64_t fpr;
|
||||
|
||||
for (size_t region = 0; region < PMM_REGIONS_MAX; region++) {
|
||||
struct pmm_region* pmm_region = &pmm.regions[region];
|
||||
|
||||
/* Inactive region, so don't bother with it. */
|
||||
if (!(pmm_region->flags & PMM_REGION_ACTIVE))
|
||||
continue;
|
||||
|
||||
spin_lock (&pmm_region->lock, &fpr);
|
||||
|
||||
/* Find starting bit of the free bit range */
|
||||
size_t bit = pmm_find_free_space_aligned (pmm_region, nblks, align_pages);
|
||||
|
||||
/* Found a free range? */
|
||||
if (bit != (size_t)-1) {
|
||||
/* Mark it */
|
||||
bm_set_region (&pmm_region->bm, bit, nblks);
|
||||
spin_unlock (&pmm_region->lock, fpr);
|
||||
|
||||
return pmm_region->membase + bit * PAGE_SIZE;
|
||||
}
|
||||
|
||||
spin_unlock (&pmm_region->lock, fpr);
|
||||
}
|
||||
|
||||
return PMM_ALLOC_ERR;
|
||||
}
|
||||
|
||||
void pmm_free (uintptr_t p_addr, size_t nblks) {
|
||||
uint64_t fpr;
|
||||
|
||||
/* Round down to nearest page boundary */
|
||||
physaddr_t aligned_p_addr = align_down (p_addr, PAGE_SIZE);
|
||||
uintptr_t aligned_p_addr = align_down (p_addr, PAGE_SIZE);
|
||||
|
||||
for (size_t region = 0; region < PMM_REGIONS_MAX; region++) {
|
||||
struct pmm_region* pmm_region = &pmm.regions[region];
|
||||
@@ -145,7 +190,7 @@ void pmm_free (physaddr_t p_addr, size_t nblks) {
|
||||
/* If aligned_p_addr is within the range if this region, it belongs to it. */
|
||||
if (aligned_p_addr >= pmm_region->membase &&
|
||||
aligned_p_addr < pmm_region->membase + pmm_region->size) {
|
||||
physaddr_t addr = aligned_p_addr - pmm_region->membase;
|
||||
uintptr_t addr = aligned_p_addr - pmm_region->membase;
|
||||
|
||||
size_t bit = div_align_up (addr, PAGE_SIZE);
|
||||
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
|
||||
#include <libk/bm.h>
|
||||
#include <libk/std.h>
|
||||
#include <mm/types.h>
|
||||
#include <sync/spin_lock.h>
|
||||
|
||||
#define PMM_ALLOC_ERR ((physaddr_t) - 1)
|
||||
#define PMM_ALLOC_ERR ((uintptr_t)-1)
|
||||
|
||||
#define PMM_REGIONS_MAX 32
|
||||
|
||||
@@ -15,7 +14,7 @@
|
||||
struct pmm_region {
|
||||
spin_lock_t lock;
|
||||
struct bm bm;
|
||||
physaddr_t membase;
|
||||
uintptr_t membase;
|
||||
size_t size;
|
||||
uint32_t flags;
|
||||
};
|
||||
@@ -25,7 +24,11 @@ struct pmm {
|
||||
};
|
||||
|
||||
void pmm_init (void);
|
||||
physaddr_t pmm_alloc (size_t nblks);
|
||||
void pmm_free (physaddr_t p_addr, size_t nblks);
|
||||
|
||||
uintptr_t pmm_alloc (size_t nblks);
|
||||
|
||||
uintptr_t pmm_alloc_aligned (size_t nblks, size_t align_pages);
|
||||
|
||||
void pmm_free (uintptr_t p_addr, size_t nblks);
|
||||
|
||||
#endif // _KERNEL_MM_PMM_H
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
#ifndef _KERNEL_MM_TYPES_H
|
||||
#define _KERNEL_MM_TYPES_H
|
||||
|
||||
#include <libk/std.h>
|
||||
|
||||
typedef uintptr_t physaddr_t;
|
||||
|
||||
#endif // _KERNEL_MM_TYPES_H
|
||||
Reference in New Issue
Block a user