AP, kmalloc
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
AALDIR=$(AALBASE)/$(TARGET)
|
||||
OBJS=setup.o mem.o debug.o mikc.o listeners.o
|
||||
OBJS=init.o mem.o debug.o mikc.o listeners.o ap.o syscall.o cls.o
|
||||
DEPSRCS=$(wildcard $(SRC)/*.c)
|
||||
|
||||
include $(SRC)/configs/config.$(TARGET)
|
||||
|
||||
23
kernel/ap.c
23
kernel/ap.c
@ -4,16 +4,32 @@
|
||||
#include <aal/mm.h>
|
||||
#include <aal/debug.h>
|
||||
|
||||
int num_processors = 1;
|
||||
static volatile int ap_stop = 1;
|
||||
|
||||
void ap_idle(void)
|
||||
{
|
||||
int id = aal_mc_get_hardware_processor_id();
|
||||
|
||||
kprintf(" %d", id);
|
||||
while (1) {
|
||||
cpu_halt();
|
||||
}
|
||||
}
|
||||
|
||||
static void ap_wait(void)
|
||||
{
|
||||
while (ap_stop) {
|
||||
cpu_pause();
|
||||
}
|
||||
|
||||
ap_idle();
|
||||
}
|
||||
|
||||
void ap_start(void)
|
||||
{
|
||||
ap_stop = 0;
|
||||
}
|
||||
|
||||
void ap_init(void)
|
||||
{
|
||||
struct aal_mc_cpu_info *cpu_info;
|
||||
@ -36,7 +52,10 @@ void ap_init(void)
|
||||
if (cpu_info->hw_ids[i] == bsp_hw_id) {
|
||||
continue;
|
||||
}
|
||||
aal_mc_boot_cpu(cpu_info->hw_ids[i], (unsigned long)ap_idle);
|
||||
aal_mc_boot_cpu(cpu_info->hw_ids[i], (unsigned long)ap_wait);
|
||||
kprintf(" %d", cpu_info->hw_ids[i]);
|
||||
|
||||
num_processors++;
|
||||
}
|
||||
kprintf(" .. Done\n");
|
||||
}
|
||||
|
||||
28
kernel/cls.c
Normal file
28
kernel/cls.c
Normal file
@ -0,0 +1,28 @@
|
||||
#include <kmsg.h>
|
||||
#include <string.h>
|
||||
#include <aal/cpu.h>
|
||||
#include <aal/debug.h>
|
||||
#include <aal/lock.h>
|
||||
#include <aal/mm.h>
|
||||
#include <aal/page_alloc.h>
|
||||
#include <cls.h>
|
||||
#include <page.h>
|
||||
|
||||
extern int num_processors;
|
||||
|
||||
static struct cpu_local_var *clv;
|
||||
|
||||
void cpu_local_var_init(void)
|
||||
{
|
||||
int z;
|
||||
|
||||
z = sizeof(struct cpu_local_var) * num_processors;
|
||||
z = (z + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
||||
|
||||
clv = allocate_pages(z, 0);
|
||||
}
|
||||
|
||||
struct cpu_local_var *get_cpu_local_var(int id)
|
||||
{
|
||||
return clv + id;
|
||||
}
|
||||
27
kernel/include/cls.h
Normal file
27
kernel/include/cls.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef __HEADER_CLS_H
|
||||
#define __HEADER_CLS_H
|
||||
/*
|
||||
* CPU Local Storage (cls)
|
||||
*/
|
||||
|
||||
struct malloc_header {
|
||||
struct malloc_header *next;
|
||||
unsigned long size;
|
||||
};
|
||||
|
||||
struct cpu_local_var {
|
||||
/* malloc */
|
||||
struct malloc_header free_list;
|
||||
/* Align to 64-byte */
|
||||
} __attribute__((aligned(64)));
|
||||
|
||||
|
||||
struct cpu_local_var *get_cpu_local_var(int id);
|
||||
static struct cpu_local_var *get_this_cpu_local_var(void)
|
||||
{
|
||||
return get_cpu_local_var(aal_mc_get_processor_id());
|
||||
}
|
||||
|
||||
#define cpu_local_var(name) get_this_cpu_local_var()->name
|
||||
|
||||
#endif
|
||||
7
kernel/include/kmalloc.h
Normal file
7
kernel/include/kmalloc.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef __HEADER_KMALLOC_H
|
||||
#define __HEADER_KMALLOC_H
|
||||
|
||||
void *kmalloc(int size, int flag);
|
||||
void kfree(void *ptr);
|
||||
|
||||
#endif
|
||||
7
kernel/include/page.h
Normal file
7
kernel/include/page.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef __HEADER_PAGE_H
|
||||
#define __HEADER_PAGE_H
|
||||
|
||||
void *allocate_pages(int npages, enum aal_mc_ap_flag flag);
|
||||
void free_pages(void *va, int npages);
|
||||
|
||||
#endif
|
||||
73
kernel/init.c
Normal file
73
kernel/init.c
Normal file
@ -0,0 +1,73 @@
|
||||
#include <types.h>
|
||||
#include <kmsg.h>
|
||||
#include <kmalloc.h>
|
||||
#include <aal/cpu.h>
|
||||
#include <aal/mm.h>
|
||||
#include <aal/debug.h>
|
||||
#include <cls.h>
|
||||
|
||||
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);
|
||||
extern void ap_init(void);
|
||||
extern void arch_ready(void);
|
||||
extern void mc_ikc_init(void);
|
||||
extern void cpu_local_var_init(void);
|
||||
extern void kmalloc_init(void);
|
||||
extern void ap_start(void);
|
||||
|
||||
static aal_mc_kernel_context_t idle_ctx;
|
||||
|
||||
static void idle(void)
|
||||
{
|
||||
while (1) {
|
||||
cpu_enable_interrupt();
|
||||
cpu_halt();
|
||||
}
|
||||
}
|
||||
|
||||
extern int syscall(int, aal_mc_user_context_t *);
|
||||
|
||||
static void handler_init(void)
|
||||
{
|
||||
aal_mc_set_syscall_handler(syscall);
|
||||
}
|
||||
|
||||
static void rest_init(void)
|
||||
{
|
||||
handler_init();
|
||||
|
||||
ap_init();
|
||||
cpu_local_var_init();
|
||||
kmalloc_init();
|
||||
mc_ikc_init();
|
||||
|
||||
ap_start();
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
kmsg_init();
|
||||
|
||||
kputs("MCK started.\n");
|
||||
|
||||
arch_init();
|
||||
|
||||
mem_init();
|
||||
|
||||
ikc_master_init();
|
||||
|
||||
rest_init();
|
||||
|
||||
arch_ready();
|
||||
|
||||
kputs("MCK/AAL booted.\n");
|
||||
|
||||
aal_mc_init_context(&idle_ctx, NULL, idle);
|
||||
aal_mc_switch_context(NULL, &idle_ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
102
kernel/mem.c
102
kernel/mem.c
@ -6,6 +6,8 @@
|
||||
#include <aal/mm.h>
|
||||
#include <aal/page_alloc.h>
|
||||
|
||||
#include <cls.h>
|
||||
|
||||
static struct aal_page_allocator_desc *pa_allocator;
|
||||
static unsigned long pa_start, pa_end;
|
||||
|
||||
@ -120,3 +122,103 @@ void mem_init(void)
|
||||
/* Prepare the kernel virtual map space */
|
||||
virtual_allocator_init();
|
||||
}
|
||||
|
||||
void kmalloc_init(void)
|
||||
{
|
||||
struct cpu_local_var *v = get_this_cpu_local_var();
|
||||
struct malloc_header *h = &v->free_list;
|
||||
|
||||
h->next = &v->free_list;
|
||||
h->size = 0;
|
||||
}
|
||||
|
||||
void *kmalloc(int size, int flag)
|
||||
{
|
||||
struct cpu_local_var *v = get_this_cpu_local_var();
|
||||
struct malloc_header *h = &v->free_list, *prev, *p;
|
||||
int u, req_page;
|
||||
|
||||
if (size >= PAGE_SIZE * 4) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u = (size + sizeof(*h) - 1) / sizeof(*h);
|
||||
|
||||
prev = h;
|
||||
h = h->next;
|
||||
|
||||
while (1) {
|
||||
if (h == &v->free_list) {
|
||||
req_page = ((u + 1) * sizeof(*h) + PAGE_SIZE - 1)
|
||||
>> PAGE_SHIFT;
|
||||
|
||||
h = allocate_pages(req_page, 0);
|
||||
prev->next = h;
|
||||
h->size = (req_page * PAGE_SIZE) / sizeof(*h) - 2;
|
||||
/* Guard entry */
|
||||
p = h + h->size + 1;
|
||||
p->next = &v->free_list;
|
||||
h->next = p;
|
||||
}
|
||||
|
||||
if (h->size >= u) {
|
||||
if (h->size == u || h->size == u + 1) {
|
||||
prev->next = h->next;
|
||||
return h + 1;
|
||||
} else { /* Divide */
|
||||
h->size -= u + 1;
|
||||
|
||||
p = h + h->size + 1;
|
||||
p->size = u;
|
||||
|
||||
return p + 1;
|
||||
}
|
||||
}
|
||||
prev = h;
|
||||
h = h->next;
|
||||
}
|
||||
}
|
||||
|
||||
void kfree(void *ptr)
|
||||
{
|
||||
struct cpu_local_var *v = get_this_cpu_local_var();
|
||||
struct malloc_header *h = &v->free_list, *p = ptr;
|
||||
int combined = 0;
|
||||
|
||||
h = h->next;
|
||||
|
||||
p--;
|
||||
|
||||
while ((p < h || p > h->next) && h != &v->free_list) {
|
||||
h = h->next;
|
||||
}
|
||||
|
||||
if (h + h->size + 1 == p && h->size != 0) {
|
||||
combined = 1;
|
||||
h->size += p->size + 1;
|
||||
}
|
||||
if (h->next == p + p->size + 1 && h->next->size != 0) {
|
||||
combined = 1;
|
||||
h->size += h->next->size + 1;
|
||||
h->next = h->next->next;
|
||||
}
|
||||
if (!combined) {
|
||||
p->next = h->next;
|
||||
h->next = p;
|
||||
}
|
||||
}
|
||||
|
||||
void print_free_list(void)
|
||||
{
|
||||
struct cpu_local_var *v = get_this_cpu_local_var();
|
||||
struct malloc_header *h = &v->free_list;
|
||||
|
||||
h = h->next;
|
||||
|
||||
kprintf("free_list : \n");
|
||||
while (h != &v->free_list) {
|
||||
kprintf(" %p : %p, %d ->\n", h, h->next, h->size);
|
||||
h = h->next;
|
||||
}
|
||||
kprintf("\n");
|
||||
}
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
#include <types.h>
|
||||
#include <kmsg.h>
|
||||
#include <aal/cpu.h>
|
||||
#include <aal/mm.h>
|
||||
#include <aal/debug.h>
|
||||
|
||||
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);
|
||||
extern void arch_ready(void);
|
||||
extern void mc_ikc_init(void);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
kmsg_init();
|
||||
|
||||
kputs("MCK started.\n");
|
||||
|
||||
arch_init();
|
||||
|
||||
mem_init();
|
||||
|
||||
ikc_master_init();
|
||||
|
||||
mc_ikc_init();
|
||||
|
||||
arch_ready();
|
||||
cpu_enable_interrupt();
|
||||
|
||||
kputs("MCK/AAL booted.\n");
|
||||
|
||||
while (1) {
|
||||
cpu_halt();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
13
kernel/syscall.c
Normal file
13
kernel/syscall.c
Normal file
@ -0,0 +1,13 @@
|
||||
#include <types.h>
|
||||
#include <kmsg.h>
|
||||
#include <aal/cpu.h>
|
||||
#include <aal/mm.h>
|
||||
#include <aal/debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
int syscall(int num, aal_mc_user_context_t *ctx)
|
||||
{
|
||||
kprintf("System call #%d\n", num);
|
||||
|
||||
return -ENOSYS;
|
||||
}
|
||||
Reference in New Issue
Block a user