diff --git a/kernel/Makefile.build b/kernel/Makefile.build index c0cbb160..a7274ac8 100644 --- a/kernel/Makefile.build +++ b/kernel/Makefile.build @@ -1,5 +1,5 @@ AALDIR=$(AALBASE)/$(TARGET) -OBJS=setup.o mem.o debug.o +OBJS=setup.o mem.o debug.o mikc.o DEPSRCS=$(wildcard $(SRC)/*.c) include $(SRC)/configs/config.$(TARGET) diff --git a/kernel/mem.c b/kernel/mem.c index fb12b3a6..39739433 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -4,112 +4,40 @@ #include #include #include +#include +static struct aal_page_allocator_desc *pa_allocator; static unsigned long pa_start, pa_end; -static unsigned long *page_map; -static aal_spinlock_t page_lock; static void reserve_pages(unsigned long start, unsigned long end, int type) { - unsigned long *m; - if (start < pa_start) { - start = pa_start; + start = pa_allocator->start; } if (end > pa_end) { - end = pa_end; + end = pa_allocator->last; } if (start >= end) { return; } - - kprintf("reserved: %lx - %lx ", start, end); - - start = (start - pa_start) >> PAGE_SHIFT; - end = (end - pa_start + PAGE_SIZE - 1) >> PAGE_SHIFT; - - kprintf(" (%d pages)\n", end - start); - - m = page_map + (start >> 6); - /* XXX: Also silly */ - for (; start < end; start++) { - *m |= (1 << (start & 63)); - if ((start & 63) == 63) - m++; - } + kprintf("reserve: %016lx - %016lx (%ld pages)\n", start, end, + (end - start) >> PAGE_SHIFT); + aal_pagealloc_reserve(pa_allocator, start, end); } -static unsigned long count_available_pages(void) +void *allocate_pages(int npages, enum aal_mc_ap_flag flag) { - unsigned long i, j, n = 0; - unsigned long size = pa_end - pa_start; - - /* XXX: Very silly counting */ - for (i = 0; i < (size >> PAGE_SHIFT) / 64; i++) { - for (j = 0; j < 64; j++) { - if (!(page_map[i] & (1UL << j))) { - n++; - } - } - } - - return n; + return phys_to_virt(aal_pagealloc_alloc(pa_allocator, npages)); } -static int is_reserved_page(unsigned long phys) +void free_pages(void *va, int npages) { - unsigned long idx; - - if (phys < pa_start || phys >= pa_end) { - return 1; - } else { - idx = (phys - pa_start) >> PAGE_SHIFT; - return !!(page_map[idx >> 6] & (1UL << (idx & 63))); - } -} - -static unsigned long last_ap_pa; - -void *allocate_page(enum aal_mc_ap_flag flag) -{ - unsigned long idx, flags; - - /* XXX: wrap around */ - flags = aal_mc_spinlock_lock(&page_lock); - - while (is_reserved_page(last_ap_pa) && last_ap_pa < pa_end) { - last_ap_pa += PAGE_SIZE; - } - if (last_ap_pa >= pa_end) { - aal_mc_spinlock_unlock(&page_lock, flags); - return NULL; - } - idx = (last_ap_pa - pa_start) >> PAGE_SHIFT; - page_map[idx >> 6] |= (1UL << (idx & 63)); - - aal_mc_spinlock_unlock(&page_lock, flags); - - return phys_to_virt(last_ap_pa); -} - -void free_page(void *va) -{ - unsigned long idx, phys, flags; - - phys = virt_to_phys(va); - if (phys < pa_start || phys >= pa_end) { - return; - } - idx = (phys - pa_start) >> PAGE_SHIFT; - - flags = aal_mc_spinlock_lock(&page_lock); - page_map[idx >> 6] &= ~(1UL << (idx & 63)); - aal_mc_spinlock_unlock(&page_lock, flags); + aal_pagealloc_free(pa_allocator, virt_to_phys(va), npages); } static struct aal_mc_pa_ops allocator = { - .alloc = allocate_page, - .free = free_page, + .alloc = allocate_pages, + .free = free_pages, }; static void page_fault_handler(unsigned long address, void *regs) @@ -119,11 +47,10 @@ static void page_fault_handler(unsigned long address, void *regs) panic("page fault"); } -void mem_init(void) +static void page_allocator_init(void) { - unsigned long pages, page_map_pa; - - aal_mc_spinlock_init(&page_lock); + unsigned long page_map_pa, pages; + void *page_map; pa_start = aal_mc_get_memory_address(AAL_MC_GMA_AVAIL_START, 0); pa_end = aal_mc_get_memory_address(AAL_MC_GMA_AVAIL_END, 0); @@ -131,22 +58,18 @@ void mem_init(void) pa_start &= PAGE_MASK; pa_end = (pa_end + PAGE_SIZE - 1) & PAGE_MASK; - pages = (pa_end - pa_start) >> PAGE_SHIFT; - - kprintf("mem_init: %lx - %lx, %d pages\n", pa_start, pa_end, pages); - page_map_pa = aal_mc_get_memory_address(AAL_MC_GMA_HEAP_START, 0); page_map = phys_to_virt(page_map_pa); - memset(page_map, 0, pages / 8); - /* TODO: Reserve if 'pages' is not a multiple of 8 */ - kprintf("page_map: %p\n", page_map); - reserve_pages(page_map_pa, page_map_pa + pages / 8, 0); + pa_allocator = __aal_pagealloc_init(pa_start, pa_end - pa_start, + PAGE_SIZE, page_map, &pages); + + reserve_pages(page_map_pa, page_map_pa + pages * PAGE_SIZE, 0); aal_mc_reserve_arch_pages(pa_start, pa_end, reserve_pages); - kprintf("Available pages: %ld pages\n", count_available_pages()); - last_ap_pa = pa_start; + kprintf("Available pages: %ld pages\n", + aal_pagealloc_count(pa_allocator)); /* Notify the aal to use my page allocator */ aal_mc_set_page_allocator(&allocator); @@ -154,3 +77,20 @@ void mem_init(void) /* And prepare some exception handlers */ aal_mc_set_page_fault_handler(page_fault_handler); } + +static struct aal_page_allocator_desc *vmap_allocator; + +static void virtual_allocator_init(void) +{ + vmap_allocator = aal_pagealloc_init(MAP_VMAP_START, + MAP_VMAP_SIZE, LARGE_PAGE_SIZE); +} + + +void mem_init(void) +{ + page_allocator_init(); + + /* Prepare the kernel virtual map space */ + virtual_allocator_init(); +} diff --git a/kernel/mikc.c b/kernel/mikc.c new file mode 100644 index 00000000..01a88b0f --- /dev/null +++ b/kernel/mikc.c @@ -0,0 +1,23 @@ +#include +#include +#include +#include + +static struct aal_ikc_channel_desc mchannel; +static int master_channel_packet_handler(void *__packet); + +void ikc_master_init(void) +{ + aal_mc_ikc_init_first(&mchannel, master_channel_packet_handler); + kprintf("done.\n"); +} + +static int master_channel_packet_handler(void *__packet) +{ + struct aal_ikc_master_packet *packet = __packet; + + /* Do something */ + + return 0; +} + diff --git a/kernel/setup.c b/kernel/setup.c index 524ccd33..f188608c 100644 --- a/kernel/setup.c +++ b/kernel/setup.c @@ -7,6 +7,7 @@ extern struct aal_kmsg_buf kmsg_buf; extern void arch_init(void); extern void kmsg_init(void); extern void mem_init(void); +extern void ikc_master_init(void); int main(void) { @@ -18,6 +19,8 @@ int main(void) mem_init(); + ikc_master_init(); + cpu_enable_interrupt(); while (1) {