summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/amd64/mem/meson.build7
-rw-r--r--arch/amd64/mem/vmap.c2
-rw-r--r--arch/amd64/mem/vmap.h12
-rw-r--r--arch/amd64/meson.build15
-rw-r--r--mem/docs/allocator.9.scd4
-rw-r--r--mem/docs/framer.9.scd4
-rw-r--r--mem/docs/vmap.9.scd80
-rw-r--r--mem/errors.h12
-rw-r--r--mem/framer.c8
-rw-r--r--mem/framer.h4
-rw-r--r--mem/meson.build3
-rw-r--r--mem/vmap.c26
-rw-r--r--mem/vmap.h31
13 files changed, 193 insertions, 15 deletions
diff --git a/arch/amd64/mem/meson.build b/arch/amd64/mem/meson.build
new file mode 100644
index 0000000..1e26a72
--- /dev/null
+++ b/arch/amd64/mem/meson.build
@@ -0,0 +1,7 @@
+amd64_mem_src = [
+ 'vmap.c'
+]
+
+amd64_mem = static_library('amd64_mem', amd64_mem_src, include_directories: amd64_inc)
+
+amd64_mod += amd64_mem \ No newline at end of file
diff --git a/arch/amd64/mem/vmap.c b/arch/amd64/mem/vmap.c
new file mode 100644
index 0000000..6bb786c
--- /dev/null
+++ b/arch/amd64/mem/vmap.c
@@ -0,0 +1,2 @@
+#include "vmap.h"
+
diff --git a/arch/amd64/mem/vmap.h b/arch/amd64/mem/vmap.h
new file mode 100644
index 0000000..c13b887
--- /dev/null
+++ b/arch/amd64/mem/vmap.h
@@ -0,0 +1,12 @@
+#ifndef AMD64_MEM_VMAP_H
+#define AMD64_MEM_VMAP_H
+
+#include <mem/vmap.h>
+
+typedef struct amd64_mem_vmap {
+ MemVmap vmap;
+
+
+} Amd64MemVmap;
+
+#endif \ No newline at end of file
diff --git a/arch/amd64/meson.build b/arch/amd64/meson.build
index 4c64c8c..03e574c 100644
--- a/arch/amd64/meson.build
+++ b/arch/amd64/meson.build
@@ -1,13 +1,18 @@
-amd64_src = [
- 'quirks.c'
-]
-
amd64_linker_sc = meson.current_source_dir() / 'linker.sc'
kernel_link_dep += amd64_linker_sc
kernel_link_arg += '-T' + amd64_linker_sc
kernel_inc += include_directories('include')
-amd64 = static_library('amd64', amd64_src, include_directories: kernel_inc)
+amd64_src = [
+ 'quirks.c'
+]
+amd64_inc = kernel_inc
+amd64_mod = []
+
+# Modules
+subdir('mem')
+
+amd64 = static_library('amd64', amd64_src, link_with: amd64_mod, include_directories: kernel_inc)
kernel_mod += amd64 \ No newline at end of file
diff --git a/mem/docs/allocator.9.scd b/mem/docs/allocator.9.scd
index df708a7..c70156a 100644
--- a/mem/docs/allocator.9.scd
+++ b/mem/docs/allocator.9.scd
@@ -1,4 +1,4 @@
-MEMALLOCATOR(9)
+MEM_ALLOCATOR(9)
# NAME
@@ -65,4 +65,4 @@ The MemAllocator interface and its dispatching functions are implemented in _mem
# SEE ALSO
-memframer(9) \ No newline at end of file
+mem_framer(9) \ No newline at end of file
diff --git a/mem/docs/framer.9.scd b/mem/docs/framer.9.scd
index 5836e19..1bc3670 100644
--- a/mem/docs/framer.9.scd
+++ b/mem/docs/framer.9.scd
@@ -1,4 +1,4 @@
-MEMFRAMER(9)
+MEM_FRAMER(9)
# NAME
@@ -18,7 +18,7 @@ void mem_framer_free(MemAllocator *self, void *ptr);
# DESCRIPTION
-*MemFramer* and its related functions is an implementation of memallocator(9) designed to manage the allocation and freeing of chunks of same size - they are called _frames_ - that are boundary aligned on multiples of that size.
+*MemFramer* and its related functions is an implementation of mem_allocator(9) designed to manage the allocation and freeing of chunks of same size - they are called _frames_ - that are boundary aligned on multiples of that size.
*MemFramer* is a linked-list allocator, meaning that when a frame is requested, it can either pop the frame from a free list (a linked list of frames that have previously been freed), or bump a new frame from the region of usable memory that it manages.
diff --git a/mem/docs/vmap.9.scd b/mem/docs/vmap.9.scd
new file mode 100644
index 0000000..89faca7
--- /dev/null
+++ b/mem/docs/vmap.9.scd
@@ -0,0 +1,80 @@
+MEM_VMAP(9)
+
+# NAME
+
+*mem_vmap_translate*, *mem_vmap_map*, *mem_vmap_unmap* - manage virtual address spaces
+
+# SYNOPSIS
+
+```
+#include <mem/vmap.h>
+
+typedef struct mem_vmap MemVmap;
+
+usize mem_vmap_translate(MemVmap *inner, usize virt);
+int mem_vmap_map(MemVmap *inner, usize phys, usize virt, usize len, int flags);
+void mem_vmap_unmap(MemVmap *inner, usize virt, usize len);
+```
+
+# DESCRIPTION
+
+Many CPUs offer the ability to specify mappings between what the CPU regular memory accesses can see, and the physical memory as laid by the machine. A set of mappings enabled at once at the same time is said to constitute a *virtual address space*, in that it is the space of addresses that are meaningful to the current execution environment of the CPU.
+
+*MemVmap* and its related utility methods are an abstraction over the hardware's memory mapping facilities to allow managing an address space and switch from an address space to another.
+
+## Translation
+
+Translation is the action of taking a virtual address and obtaining its physical address. A CPU supporting memory mapping can do this relatively efficiently compared with simulating it in software.
+
+The *mem_vmap_translate()* function translates a virtual address into its physical one in software. This can be useful for a few reasons and this mechanism is used internally by MemVmap implementation themselves. *mem_vmap_translate()* takes the following arguments:
+
+ _inner_ The *MemVmap* to use
+ _virt_ The virtual address to translate
+
+If the translation lands on an unmapped region of the virtual address space, the miss flag is set.
+
+## Mapping
+
+The *mem_vmap_map()* function maps a region of physical memory into the specified virtual address space, around a specified virtual address, with some flags. *mem_vmap_map()* takes the following arguments:
+
+ _inner_ The *MemVmap* to use
+ _phys_ The beginning of the physical memory region that will back the map
+ _virt_ The beginning of the virtual memory region to which the physical memory shall be mapped
+ _len_ The length of the region in char-sized units
+ _flags_ The flags with which the region must be mapped
+
+The mapping operation may fail for reasons, such as:
+ - The requested mapping overlaps with a pre-existing mapping
+
+## Unmapping
+
+Unmapping is the inverse operation of mapping, it removes a particular map from the set of mappings.
+
+The *mem_vmap_unmap()* function is used to perform the unmap operation on a particular address space at a specified virtual address. *mem_vmap_unmap()* takes the following arguments:
+
+ _inner_ The *MemVmap* to use
+ _virt_ The beginning of the virtual memory region that must be unmapped
+ _len_ The length of the virtual memory region that must be unmapped
+
+Note: it is not an error to unmap a region of virtual memory that is not already mapped. The unmap operation, if properly implemented, should not fail.
+
+# Switching
+
+The *mem_vmap_switch_to()* functions is used to enable a particular address space. It takes only one argument, _inner_ the address space to switch to.
+
+Note: the caller should naturally make sure that the current code being executed, along with the required data, is correctly mapped at the according places in the target address space.
+
+# FLAGS
+
+XXX todo, unimplemented yet
+
+# RETURN VALUES
+
+*mem_vmap_translate()* returns a physical address on success, 0 in case of error or miss
+*mem_vmap_map()* returns 0 in case of success, or a non-zero value in case of error
+
+Refer to mem/errors.h for the list of error codes pertaining to the _mem_ module
+
+# CODE REFERENCES
+
+*MemVmap* and its related functions are defined in _mem/vmap.c_. Also refer to its particular implementations. \ No newline at end of file
diff --git a/mem/errors.h b/mem/errors.h
new file mode 100644
index 0000000..e926214
--- /dev/null
+++ b/mem/errors.h
@@ -0,0 +1,12 @@
+#ifndef MEM_ERRORS_H
+#define MEM_ERRORS_H
+
+enum mem_error {
+ MEM_OK = 0,
+
+ /* Returned when an implementation does not support
+ one of the vmap operations */
+ MEM_VMAP_UNSUPPORTED
+};
+
+#endif \ No newline at end of file
diff --git a/mem/framer.c b/mem/framer.c
index 9a66feb..dbd8c9a 100644
--- a/mem/framer.c
+++ b/mem/framer.c
@@ -23,9 +23,9 @@ MemFramer *mem_framer_install(void *addr, usize end, uint blksz) {
void *mem_framer_alloc(MemAllocator *inner, usize n) {
/* When allocating a frame, we have two paths:
1. The freelist is not empty: give away
- the last freed frame
- 2. The freelist is empty: bump away the next
- frame (pointed at by the next member)
+ the last freed frame
+ 2. The freelist is empty: bump away the next
+ frame (pointed at by the next member)
The alloc must fail the freelist is empty and that
the next is beyond the end of the region */
@@ -53,7 +53,7 @@ void *mem_framer_alloc(MemAllocator *inner, usize n) {
void mem_framer_free(MemAllocator *inner, void *ptr) {
/* NOTE: this implementation does make the assumption
that the given pointer is the base of the allocated
- region without correction */
+ region without correction */
MemFramer *self = (MemFramer*)inner;
diff --git a/mem/framer.h b/mem/framer.h
index 6d7034b..e2a6945 100644
--- a/mem/framer.h
+++ b/mem/framer.h
@@ -5,6 +5,8 @@
#include "allocator.h"
+/* Represents a free frame as part of the freelist, this is done
+ in order to avoid having to do annoying casts */
typedef struct mem_framer_freed {
struct mem_framer_freed *next;
} MemFramerFreed;
@@ -24,7 +26,7 @@ typedef struct mem_framer {
the freelist
NOTE: the freelist is a singly-linked list comprising
all frames that have been previously allocated
- and then freed */
+ and then freed */
MemFramerFreed *free;
/* The size of a frame. This value also defines the alignment
diff --git a/mem/meson.build b/mem/meson.build
index ec4a984..e4db123 100644
--- a/mem/meson.build
+++ b/mem/meson.build
@@ -1,6 +1,7 @@
mem_src = [
'allocator.c',
- 'framer.c'
+ 'framer.c',
+ 'vmap.c'
]
mem = static_library('mem', mem_src, include_directories: kernel_inc)
diff --git a/mem/vmap.c b/mem/vmap.c
new file mode 100644
index 0000000..618b19e
--- /dev/null
+++ b/mem/vmap.c
@@ -0,0 +1,26 @@
+#include "vmap.h"
+#include "errors.h"
+
+usize mem_vmap_translate(MemVmap *inner, usize virt) {
+ if (inner->translate)
+ return inner->translate(inner, virt);
+
+ return 0;
+}
+
+int mem_vmap_map(MemVmap *inner, usize phys, usize virt, usize len, int flags) {
+ if (inner->map)
+ return inner->map(inner, phys, virt, len, flags);
+
+ return MEM_VMAP_UNSUPPORTED;
+}
+
+void mem_vmap_unmap(MemVmap *inner, usize virt, usize len) {
+ if (inner->unmap)
+ inner->unmap(inner, virt, len);
+}
+
+void mem_vmap_switch_to(MemVmap *inner) {
+ if (inner->switch_to)
+ inner->switch_to(inner);
+} \ No newline at end of file
diff --git a/mem/vmap.h b/mem/vmap.h
new file mode 100644
index 0000000..4e1816c
--- /dev/null
+++ b/mem/vmap.h
@@ -0,0 +1,31 @@
+#ifndef MEM_VMAP_H
+#define MEM_VMAP_H
+
+#include <rt.h>
+
+typedef struct mem_vmap MemVmap;
+
+typedef usize (*MemVmapTranslate)(MemVmap *, usize);
+typedef int (*MemVmapMap)(MemVmap *, usize, usize, usize, int);
+typedef int (*MemVmapUnmap)(MemVmap *, usize, usize);
+typedef void (*MemVmapSwitchTo)(MemVmap *);
+
+/* Structure abstracting the memory mapping facilities of
+ the machine */
+struct mem_vmap {
+ MemVmapTranslate translate;
+ MemVmapMap map;
+ MemVmapUnmap unmap;
+ MemVmapSwitchTo switch_to;
+
+ /* Flag indicating whether the previous translation
+ lead to a miss */
+ int miss;
+};
+
+usize mem_vmap_translate(MemVmap *inner, usize virt);
+int mem_vmap_map(MemVmap *inner, usize phys, usize virt, usize len, int flags);
+void mem_vmap_unmap(MemVmap *inner, usize virt, usize len);
+void mem_vmap_switch_to(MemVmap *inner);
+
+#endif \ No newline at end of file