summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rwxr-xr-xfreebsd-to-rtems.py1
-rw-r--r--rtemsbsd/include/machine/rtems-bsd-page.h92
-rw-r--r--rtemsbsd/rtems/rtems-bsd-page.c149
4 files changed, 243 insertions, 0 deletions
diff --git a/Makefile b/Makefile
index a3a02a30..6c0625b9 100644
--- a/Makefile
+++ b/Makefile
@@ -83,6 +83,7 @@ LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-mutex.c
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-muteximpl.c
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-newproc.c
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-nexus.c
+LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-page.c
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-panic.c
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-pci_bus.c
LIB_C_FILES += rtemsbsd/rtems/rtems-bsd-pci_cfgreg.c
diff --git a/freebsd-to-rtems.py b/freebsd-to-rtems.py
index ab335223..439c4b17 100755
--- a/freebsd-to-rtems.py
+++ b/freebsd-to-rtems.py
@@ -681,6 +681,7 @@ rtems.addRTEMSSourceFiles(
'rtems/rtems-bsd-muteximpl.c',
'rtems/rtems-bsd-newproc.c',
'rtems/rtems-bsd-nexus.c',
+ 'rtems/rtems-bsd-page.c',
'rtems/rtems-bsd-panic.c',
'rtems/rtems-bsd-pci_bus.c',
'rtems/rtems-bsd-pci_cfgreg.c',
diff --git a/rtemsbsd/include/machine/rtems-bsd-page.h b/rtemsbsd/include/machine/rtems-bsd-page.h
new file mode 100644
index 00000000..b732c1a9
--- /dev/null
+++ b/rtemsbsd/include/machine/rtems-bsd-page.h
@@ -0,0 +1,92 @@
+/**
+ * @file
+ *
+ * @ingroup rtems_bsd_machine
+ *
+ * @brief TODO.
+ */
+
+/*
+ * Copyright (c) 2015 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _RTEMS_BSD_MACHINE_RTEMS_BSD_PAGE_H_
+#define _RTEMS_BSD_MACHINE_RTEMS_BSD_PAGE_H_
+
+/*
+ * A page is a fixed size memory area of size PAGE_SIZE with the ability to
+ * associate an object with it. The memory pool for pages has a fixed size and
+ * is allocated during system initialization. This API is intended to be used
+ * by ZONE(9).
+ */
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <stdint.h>
+
+__BEGIN_DECLS
+
+extern void **rtems_bsd_page_object_table;
+
+extern uintptr_t rtems_bsd_page_area_begin;
+
+void *rtems_bsd_page_alloc(uintptr_t size_in_bytes, int wait);
+
+void rtems_bsd_page_free(void *addr);
+
+static inline void **
+rtems_bsd_page_get_object_entry(void *addr)
+{
+ uintptr_t a = (uintptr_t)addr;
+ uintptr_t b = rtems_bsd_page_area_begin;
+ uintptr_t s = PAGE_SHIFT;
+
+ return (&rtems_bsd_page_object_table[(a - b) >> s]);
+}
+
+static inline void *
+rtems_bsd_page_get_object(void *addr)
+{
+ void **obj_entry = rtems_bsd_page_get_object_entry(addr);
+
+ return (*obj_entry);
+}
+
+static inline void
+rtems_bsd_page_set_object(void *addr, void *obj)
+{
+ void **obj_entry = rtems_bsd_page_get_object_entry(addr);
+
+ *obj_entry = obj;
+}
+
+__END_DECLS
+
+#endif /* _RTEMS_BSD_MACHINE_RTEMS_BSD_PAGE_H_ */
diff --git a/rtemsbsd/rtems/rtems-bsd-page.c b/rtemsbsd/rtems/rtems-bsd-page.c
new file mode 100644
index 00000000..929d466d
--- /dev/null
+++ b/rtemsbsd/rtems/rtems-bsd-page.c
@@ -0,0 +1,149 @@
+/**
+ * @file
+ *
+ * @ingroup rtems_bsd_rtems
+ *
+ * @brief TODO.
+ */
+
+/*
+ * Copyright (c) 2015 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <machine/rtems-bsd-kernel-space.h>
+#include <machine/rtems-bsd-page.h>
+
+#include <rtems/bsd/sys/param.h>
+#include <rtems/bsd/sys/types.h>
+#include <rtems/bsd/sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <vm/uma.h>
+
+#include <stdlib.h>
+
+#include <rtems/malloc.h>
+#include <rtems/rbheap.h>
+
+/* FIXME: This must be application configurable */
+#define PAGE_HEAP_SIZE (8 * 1024 * 1024)
+
+void **rtems_bsd_page_object_table;
+
+uintptr_t rtems_bsd_page_area_begin;
+
+static rtems_rbheap_control page_heap;
+
+struct mtx page_heap_mtx;
+
+void *
+rtems_bsd_page_alloc(uintptr_t size_in_bytes, int wait)
+{
+ void *addr;
+
+ mtx_lock(&page_heap_mtx);
+
+ addr = rtems_rbheap_allocate(&page_heap, size_in_bytes);
+ if (addr == NULL && wait) {
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ mtx_unlock(&page_heap_mtx);
+ uma_reclaim();
+ mtx_lock(&page_heap_mtx);
+
+ addr = rtems_rbheap_allocate(&page_heap, size_in_bytes);
+ if (addr != NULL)
+ break;
+
+ msleep(&page_heap, &page_heap_mtx, 0,
+ "page alloc", (hz / 4) * (i + 1));
+ }
+
+ if (i == 8) {
+ panic("rtems_bsd_page_alloc: page starvation");
+ }
+ }
+
+ mtx_unlock(&page_heap_mtx);
+
+ return (addr);
+}
+
+void
+rtems_bsd_page_free(void *addr)
+{
+ mtx_lock(&page_heap_mtx);
+ rtems_rbheap_free(&page_heap, addr);
+ wakeup(&page_heap);
+ mtx_unlock(&page_heap_mtx);
+}
+
+static void
+rtems_bsd_page_init(void *arg)
+{
+ rtems_status_code sc;
+ void *area;
+ void **obj_table;
+ rtems_rbheap_chunk *chunks;
+ size_t i;
+ size_t n;
+
+ mtx_init(&page_heap_mtx, "page heap", NULL, MTX_DEF);
+
+ area = rtems_heap_allocate_aligned_with_boundary(PAGE_HEAP_SIZE,
+ PAGE_SIZE, 0);
+ BSD_ASSERT(area != NULL);
+
+ sc = rtems_rbheap_initialize(&page_heap, area, PAGE_HEAP_SIZE,
+ PAGE_SIZE, rtems_rbheap_extend_descriptors_with_malloc, NULL);
+ BSD_ASSERT(sc == RTEMS_SUCCESSFUL);
+
+ rtems_rbheap_set_extend_descriptors(&page_heap,
+ rtems_rbheap_extend_descriptors_never);
+
+ n = PAGE_HEAP_SIZE / PAGE_SIZE;
+
+ chunks = malloc(n * sizeof(*chunks), M_RTEMS_HEAP, M_NOWAIT);
+ BSD_ASSERT(chunks != NULL);
+
+ for (i = 0; i < n; ++i) {
+ rtems_rbheap_add_to_spare_descriptor_chain(&page_heap,
+ &chunks[i]);
+ }
+
+ obj_table = calloc(n, sizeof(*obj_table));
+
+ rtems_bsd_page_area_begin = (uintptr_t)area;
+ rtems_bsd_page_object_table = obj_table;
+}
+
+SYSINIT(rtems_bsd_page, SI_SUB_VM, SI_ORDER_FIRST, rtems_bsd_page_init, NULL);