9os

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 2f3d4c8b6a3a403f13f2939e3e1747b02f908e5c
parent 5d44b84a3a47e87468712ff5a75ad61f8ac52343
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Thu, 15 Oct 2020 22:11:39 +0200

os9: Create allocb()

Allocb() is a buffer allocate which returns blocks of
page size that are correctly aligned. The fine grain
allocator (alloc()) is implemented using as base allocb().

Change-Id: Ibf0583a7e015e49b1c4bf2b1b0d1f7d82884ad2c

Diffstat:
Minclude/os9/os9.h | 9+++++----
Msrc/os9/alloc.c | 42+++++++++++++++++++++++++++++++++++-------
Msrc/os9/arch/arm64/Makefile | 1+
Asrc/os9/arch/arm64/fvpasm.s | 2++
Msrc/os9/arch/arm64/mmu.c | 51+++++----------------------------------------------
5 files changed, 48 insertions(+), 57 deletions(-)

diff --git a/include/os9/os9.h b/include/os9/os9.h @@ -18,14 +18,14 @@ #define NR_PROCS 32 #define NR_WINS 32 -#define PAGESIZE 4096 -#define ENABLE 1 -#define DISABLE 0 - #define KiB 1024u #define MiB (1024u * KiB) #define GiB (1024ul * MiB) +#define PAGESIZE (4 * KiB) +#define ENABLE 1 +#define DISABLE 0 + #define QID(t, v, p) ((Qid) {.type = (t), .vers = (v), .path = (p)}) #define SEEK_SET 0 @@ -199,6 +199,7 @@ struct win { /* alloc.c */ extern void *alloc(size_t size); +extern void *allocb(int); /* dlang.c */ extern int debug(void); diff --git a/src/os9/alloc.c b/src/os9/alloc.c @@ -1,34 +1,62 @@ #include <os9/os9.h> -#define HEAPSIZ (4 *KiB) +#include <string.h> + +#define NR_BUFFERS 512 +#define HEAPSIZ (4 * PAGESIZE) union bucket { long long ll; uintptr_t up; }; +extern char buffertab[NR_BUFFERS][PAGESIZE]; + +void * +allocb(int n) +{ + void *addr; + static unsigned long npages; + static mutex_t m; + + lock(&m); + if (npages + n>= NR_BUFFERS) + panic("out of memory"); + else + addr= buffertab[npages]; + npages += n; + unlock(&m); + + return memset(addr, 0, PAGESIZE); +} + void * alloc(size_t size) { - static union bucket heap[HEAPSIZ / sizeof(union bucket)]; - static union bucket *base = heap; - static int lock; + static int lockalloc; size_t n; union bucket *bp; + static union bucket *base, *heap; + mutex_t m; if (size == 0) { - lock = 1; + lockalloc = 1; return NULL; } - n = size-1 / sizeof(union bucket) + 1; - if (lock) + if (lockalloc) panic("alloc with lock"); + lock(&m); + if (!base) + base = heap = allocb(HEAPSIZ/ PAGESIZE); + + n = (size-1) / sizeof(union bucket) + 1; bp = base; if (&bp[size] > &heap[HEAPSIZ]) panic("out of memory"); base += n; + unlock(&m); return bp; } diff --git a/src/os9/arch/arm64/Makefile b/src/os9/arch/arm64/Makefile @@ -11,6 +11,7 @@ OBJS =\ sysreg.o\ panic.o\ fvp.o\ + fvpasm.o\ crt.o\ fpu.o\ mmu.o\ diff --git a/src/os9/arch/arm64/fvpasm.s b/src/os9/arch/arm64/fvpasm.s @@ -0,0 +1,2 @@ + .GLOBL buffertab + .EQU buffertab,0xFFFFFF0000080000 diff --git a/src/os9/arch/arm64/mmu.c b/src/os9/arch/arm64/mmu.c @@ -136,39 +136,6 @@ #define NRALLOC 0ull #define NWALLOC 0ull -static long ntables; -static phyaddr_t tables; - -static pte_t -newtab(void) -{ - phyaddr_t addr; - static long n; - static mutex_t m; - - /* - * TODO: define tables as an assembler symbol - */ - lock(&m); - if (n == ntables) { - errno = ENOMEM; - addr = INVALID; - } else { - addr = tables + n*4ll*KiB; - n++; - } - unlock(&m); - - dbg("allocate page table at %llx\n", addr); - - if (MASK(addr) != addr) - panic("invalid page table"); - - memset((void *) addr, 0, 4*KiB); - - return addr ; -} - static pte_t * walker(uintptr_t va) { @@ -185,8 +152,7 @@ walker(uintptr_t va) e = bp[n]; if (e == INVALID) { - if ((e = newtab()) == INVALID) - return NULL; + e = (pte_t) allocb(1); bp[n] = e | TABLE; barrier(DATA); } @@ -198,7 +164,7 @@ walker(uintptr_t va) return &bp[TINDEX(3, va)]; } -int +void vmap(phyaddr_t pa, uintptr_t va, int perm) { static mutex_t m; @@ -214,8 +180,7 @@ vmap(phyaddr_t pa, uintptr_t va, int perm) if (va & 1ull<<63) attr |= EL0; - if ((p = walker(va)) == NULL) - return -1; + p = walker(va); /* * locking is needed if we are in a system @@ -232,8 +197,6 @@ vmap(phyaddr_t pa, uintptr_t va, int perm) unlock(&m); dbg("page %p: %llx\n", p, MASK(pa) | attr); - - return 0; } int @@ -260,8 +223,7 @@ mapseg(Map *mp) n = (mp->siz + 4*KiB-1)/(4*KiB); for (i = 0; i < n; i++) { - if (vmap(pa, va, mp->perm) < 0) - return -1; + vmap(pa, va, mp->perm); pa += 4*KiB; va += 4*KiB; } @@ -281,7 +243,7 @@ kernelmap(void) * FIXME: We are using a full page when * we only need 16 bytes with 16 byte alignment. */ - syswr(TTBR1_EL1, newtab()); + syswr(TTBR1_EL1, (pte_t) allocb(1)); dbg("TTBR_EL1=%llx\n", sysrd(TTBR1_EL1)); @@ -327,9 +289,6 @@ immu(void) if (TGRAN4(id) != 0 || TGRAN64(id) != 0 || PAR(id) < I1TB) panic("unsupported mmu"); - ntables = mach.ntables; - tables = mach.tables; - mair = DEVICE(nGnRnE) << 56 | DEVICE(nGnRE) << 48 |