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:
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 |