AP, kmalloc

This commit is contained in:
Taku Shimosawa
2011-11-06 19:27:09 +09:00
parent 5ddd25df98
commit 83a17650b9
10 changed files with 279 additions and 42 deletions

View File

@ -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)

View File

@ -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
View 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
View 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
View 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
View 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
View 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;
}

View File

@ -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");
}

View File

@ -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
View 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;
}