Compare commits

..

2 Commits

Author SHA1 Message Date
40649c8b46 resolver: Resolve hostname to loopback address
We don't currently support loopback adapters, but some ports were trying
to resolve it.
2025-04-22 00:42:34 +03:00
996c5ebe74 LibC: Implement strxfrm_l 2025-04-22 00:41:59 +03:00
815 changed files with 9469 additions and 46742 deletions

1
.gitignore vendored
View File

@@ -3,4 +3,3 @@
build/ build/
base/ base/
script/fakeroot-context script/fakeroot-context
tools/update-image-perms

View File

@@ -18,78 +18,78 @@ namespace BAN
using const_iterator = ConstIteratorSimple<T, Array>; using const_iterator = ConstIteratorSimple<T, Array>;
public: public:
constexpr Array() = default; Array() = default;
constexpr Array(const T&); Array(const T&);
iterator begin() { return iterator(m_data); } iterator begin() { return iterator(m_data); }
iterator end() { return iterator(m_data + size()); } iterator end() { return iterator(m_data + size()); }
const_iterator begin() const { return const_iterator(m_data); } const_iterator begin() const { return const_iterator(m_data); }
const_iterator end() const { return const_iterator(m_data + size()); } const_iterator end() const { return const_iterator(m_data + size()); }
constexpr const T& operator[](size_type) const; const T& operator[](size_type) const;
constexpr T& operator[](size_type); T& operator[](size_type);
constexpr const T& back() const; const T& back() const;
constexpr T& back(); T& back();
constexpr const T& front() const; const T& front() const;
constexpr T& front(); T& front();
Span<T> span() { return Span(m_data, size()); } Span<T> span() { return Span(m_data, size()); }
Span<const T> span() const { return Span(m_data, size()); } const Span<T> span() const { return Span(m_data, size()); }
constexpr size_type size() const; constexpr size_type size() const;
constexpr const T* data() const { return m_data; } const T* data() const { return m_data; }
constexpr T* data() { return m_data; } T* data() { return m_data; }
private: private:
T m_data[S] {}; T m_data[S] {};
}; };
template<typename T, size_t S> template<typename T, size_t S>
constexpr Array<T, S>::Array(const T& value) Array<T, S>::Array(const T& value)
{ {
for (size_type i = 0; i < S; i++) for (size_type i = 0; i < S; i++)
m_data[i] = value; m_data[i] = value;
} }
template<typename T, size_t S> template<typename T, size_t S>
constexpr const T& Array<T, S>::operator[](size_type index) const const T& Array<T, S>::operator[](size_type index) const
{ {
ASSERT(index < S); ASSERT(index < S);
return m_data[index]; return m_data[index];
} }
template<typename T, size_t S> template<typename T, size_t S>
constexpr T& Array<T, S>::operator[](size_type index) T& Array<T, S>::operator[](size_type index)
{ {
ASSERT(index < S); ASSERT(index < S);
return m_data[index]; return m_data[index];
} }
template<typename T, size_t S> template<typename T, size_t S>
constexpr const T& Array<T, S>::back() const const T& Array<T, S>::back() const
{ {
ASSERT(S != 0); ASSERT(S != 0);
return m_data[S - 1]; return m_data[S - 1];
} }
template<typename T, size_t S> template<typename T, size_t S>
constexpr T& Array<T, S>::back() T& Array<T, S>::back()
{ {
ASSERT(S != 0); ASSERT(S != 0);
return m_data[S - 1]; return m_data[S - 1];
} }
template<typename T, size_t S> template<typename T, size_t S>
constexpr const T& Array<T, S>::front() const const T& Array<T, S>::front() const
{ {
ASSERT(S != 0); ASSERT(S != 0);
return m_data[0]; return m_data[0];
} }
template<typename T, size_t S> template<typename T, size_t S>
constexpr T& Array<T, S>::front() T& Array<T, S>::front()
{ {
ASSERT(S != 0); ASSERT(S != 0);
return m_data[0]; return m_data[0];

View File

@@ -34,11 +34,6 @@ namespace BAN
const T& back() const; const T& back() const;
T& back(); T& back();
const T& operator[](size_t index) const;
T& operator[](size_t index);
void clear();
size_type size() const { return m_size; } size_type size() const { return m_size; }
bool empty() const { return size() == 0; } bool empty() const { return size() == 0; }
bool full() const { return size() == capacity(); } bool full() const { return size() == capacity(); }
@@ -58,7 +53,8 @@ namespace BAN
template<typename T, size_t S> template<typename T, size_t S>
CircularQueue<T, S>::~CircularQueue() CircularQueue<T, S>::~CircularQueue()
{ {
clear(); for (size_type i = 0; i < m_size; i++)
element_at((m_first + i) % capacity())->~T();
} }
template<typename T, size_t S> template<typename T, size_t S>
@@ -119,28 +115,6 @@ namespace BAN
return *element_at((m_first + m_size - 1) % capacity()); return *element_at((m_first + m_size - 1) % capacity());
} }
template<typename T, size_t S>
const T& CircularQueue<T, S>::operator[](size_t index) const
{
ASSERT(index < m_size);
return *element_at((m_first + index) % capacity());
}
template<typename T, size_t S>
T& CircularQueue<T, S>::operator[](size_t index)
{
ASSERT(index < m_size);
return *element_at((m_first + index) % capacity());
}
template<typename T, size_t S>
void CircularQueue<T, S>::clear()
{
for (size_type i = 0; i < m_size; i++)
element_at((m_first + i) % capacity())->~T();
m_size = 0;
}
template<typename T, size_t S> template<typename T, size_t S>
const T* CircularQueue<T, S>::element_at(size_type index) const const T* CircularQueue<T, S>::element_at(size_type index) const
{ {

View File

@@ -9,35 +9,29 @@
#include <BAN/Formatter.h> #include <BAN/Formatter.h>
#include <stdio.h> #include <stdio.h>
#define __debug_putchar [](int c) { putc_unlocked(c, stddbg); } #define __debug_putchar [](int c) { putc(c, stddbg); }
#define dprintln(...) \ #define dprintln(...) \
do { \ do { \
flockfile(stddbg); \
BAN::Formatter::print(__debug_putchar, __VA_ARGS__); \ BAN::Formatter::print(__debug_putchar, __VA_ARGS__); \
BAN::Formatter::print(__debug_putchar,"\n"); \ BAN::Formatter::print(__debug_putchar,"\r\n"); \
fflush(stddbg); \ fflush(stddbg); \
funlockfile(stddbg); \
} while (false) } while (false)
#define dwarnln(...) \ #define dwarnln(...) \
do { \ do { \
flockfile(stddbg); \
BAN::Formatter::print(__debug_putchar, "\e[33m"); \ BAN::Formatter::print(__debug_putchar, "\e[33m"); \
BAN::Formatter::print(__debug_putchar, __VA_ARGS__); \ BAN::Formatter::print(__debug_putchar, __VA_ARGS__); \
BAN::Formatter::print(__debug_putchar, "\e[m\n"); \ BAN::Formatter::print(__debug_putchar, "\e[m\r\n"); \
fflush(stddbg); \ fflush(stddbg); \
funlockfile(stddbg); \
} while(false) } while(false)
#define derrorln(...) \ #define derrorln(...) \
do { \ do { \
flockfile(stddbg); \
BAN::Formatter::print(__debug_putchar, "\e[31m"); \ BAN::Formatter::print(__debug_putchar, "\e[31m"); \
BAN::Formatter::print(__debug_putchar, __VA_ARGS__); \ BAN::Formatter::print(__debug_putchar, __VA_ARGS__); \
BAN::Formatter::print(__debug_putchar, "\e[m\n"); \ BAN::Formatter::print(__debug_putchar, "\e[m\r\n"); \
fflush(stddbg); \ fflush(stddbg); \
funlockfile(stddbg); \
} while(false) } while(false)
#define dprintln_if(cond, ...) \ #define dprintln_if(cond, ...) \

View File

@@ -1,89 +0,0 @@
#pragma once
#include <BAN/Iterators.h>
#include <BAN/Swap.h>
#include <BAN/Traits.h>
namespace BAN
{
namespace detail
{
template<typename It, typename Comp>
void heapify_up(It begin, size_t index, Comp comp)
{
size_t parent = (index - 1) / 2;
while (parent < index)
{
if (comp(*(begin + index), *(begin + parent)))
break;
swap(*(begin + parent), *(begin + index));
index = parent;
parent = (index - 1) / 2;
}
}
template<typename It, typename Comp>
void heapify_down(It begin, size_t index, size_t len, Comp comp)
{
for (;;)
{
const size_t lchild = 2 * index + 1;
const size_t rchild = 2 * index + 2;
size_t child = 0;
if (lchild < len && !comp(*(begin + lchild), *(begin + index)))
{
if (rchild < len && !comp(*(begin + rchild), *(begin + lchild)))
child = rchild;
else
child = lchild;
}
else if (rchild < len && !comp(*(begin + rchild), *(begin + index)))
child = rchild;
else
break;
swap(*(begin + child), *(begin + index));
index = child;
}
}
}
template<typename It, typename Comp = less<it_value_type_t<It>>>
void make_heap(It begin, It end, Comp comp = {})
{
const size_t len = distance(begin, end);
if (len <= 1)
return;
size_t index = (len - 2) / 2;
while (index < len)
detail::heapify_down(begin, index--, len, comp);
}
template<typename It, typename Comp = less<it_value_type_t<It>>>
void push_heap(It begin, It end, Comp comp = {})
{
const size_t len = distance(begin, end);
detail::heapify_up(begin, len - 1, comp);
}
template<typename It, typename Comp = less<it_value_type_t<It>>>
void pop_heap(It begin, It end, Comp comp = {})
{
const size_t len = distance(begin, end);
swap(*begin, *(begin + len - 1));
detail::heapify_down(begin, 0, len - 1, comp);
}
template<typename It, typename Comp = less<it_value_type_t<It>>>
void sort_heap(It begin, It end, Comp comp = {})
{
while (begin != end)
pop_heap(begin, end--, comp);
}
}

View File

@@ -9,10 +9,6 @@ namespace BAN
struct IPv4Address struct IPv4Address
{ {
constexpr IPv4Address()
: IPv4Address(0)
{ }
constexpr IPv4Address(uint32_t u32_address) constexpr IPv4Address(uint32_t u32_address)
{ {
raw = u32_address; raw = u32_address;

View File

@@ -36,11 +36,12 @@ namespace BAN::Math
template<integral T> template<integral T>
inline constexpr T gcd(T a, T b) inline constexpr T gcd(T a, T b)
{ {
T t;
while (b) while (b)
{ {
T temp = b; t = b;
b = a % b; b = a % b;
a = temp; a = t;
} }
return a; return a;
} }
@@ -65,20 +66,25 @@ namespace BAN::Math
return (x & (x - 1)) == 0; return (x & (x - 1)) == 0;
} }
template<integral T> template<BAN::integral T>
__attribute__((always_inline)) static constexpr bool will_multiplication_overflow(T a, T b)
inline constexpr bool will_multiplication_overflow(T a, T b)
{ {
T dummy; if (a == 0 || b == 0)
return __builtin_mul_overflow(a, b, &dummy); return false;
if ((a > 0) == (b > 0))
return a > BAN::numeric_limits<T>::max() / b;
else
return a < BAN::numeric_limits<T>::min() / b;
} }
template<integral T> template<BAN::integral T>
__attribute__((always_inline)) static constexpr bool will_addition_overflow(T a, T b)
inline constexpr bool will_addition_overflow(T a, T b)
{ {
T dummy; if (a > 0 && b > 0)
return __builtin_add_overflow(a, b, &dummy); return a > BAN::numeric_limits<T>::max() - b;
if (a < 0 && b < 0)
return a < BAN::numeric_limits<T>::min() - b;
return false;
} }
template<typename T> template<typename T>
@@ -92,19 +98,6 @@ namespace BAN::Math
return sizeof(T) * 8 - __builtin_clzll(x) - 1; return sizeof(T) * 8 - __builtin_clzll(x) - 1;
} }
// This is ugly but my clangd does not like including
// intrinsic headers at all
#if !defined(__SSE__) || !defined(__SSE2__)
#pragma GCC push_options
#ifndef __SSE__
#pragma GCC target("sse")
#endif
#ifndef __SSE2__
#pragma GCC target("sse2")
#endif
#define BAN_MATH_POP_OPTIONS
#endif
template<floating_point T> template<floating_point T>
inline constexpr T floor(T x) inline constexpr T floor(T x)
{ {
@@ -166,23 +159,7 @@ namespace BAN::Math
"jne 1b;" "jne 1b;"
: "+t"(a) : "+t"(a)
: "u"(b) : "u"(b)
: "ax", "cc" : "ax"
);
return a;
}
template<floating_point T>
inline constexpr T remainder(T a, T b)
{
asm(
"1:"
"fprem1;"
"fnstsw %%ax;"
"testb $4, %%ah;"
"jne 1b;"
: "+t"(a)
: "u"(b)
: "ax", "cc"
); );
return a; return a;
} }
@@ -190,7 +167,7 @@ namespace BAN::Math
template<floating_point T> template<floating_point T>
static T modf(T x, T* iptr) static T modf(T x, T* iptr)
{ {
const T frac = BAN::Math::fmod<T>(x, (T)1.0); const T frac = BAN::Math::fmod<T>(x, 1);
*iptr = x - frac; *iptr = x - frac;
return frac; return frac;
} }
@@ -198,15 +175,15 @@ namespace BAN::Math
template<floating_point T> template<floating_point T>
inline constexpr T frexp(T num, int* exp) inline constexpr T frexp(T num, int* exp)
{ {
if (num == (T)0.0) if (num == 0.0)
{ {
*exp = 0; *exp = 0;
return (T)0.0; return 0.0;
} }
T e; T _exp;
asm("fxtract" : "+t"(num), "=u"(e)); asm("fxtract" : "+t"(num), "=u"(_exp));
*exp = (int)e + 1; *exp = (int)_exp + 1;
return num / (T)2.0; return num / (T)2.0;
} }
@@ -274,7 +251,6 @@ namespace BAN::Math
"fstp %%st(1);" "fstp %%st(1);"
: "+t"(x) : "+t"(x)
); );
return x; return x;
} }
@@ -287,9 +263,18 @@ namespace BAN::Math
template<floating_point T> template<floating_point T>
inline constexpr T pow(T x, T y) inline constexpr T pow(T x, T y)
{ {
if (x == (T)0.0) asm(
return (T)0.0; "fyl2x;"
return exp2<T>(y * log2<T>(x)); "fld1;"
"fld %%st(1);"
"fprem;"
"f2xm1;"
"faddp;"
"fscale;"
: "+t"(x), "+u"(y)
);
return x;
} }
template<floating_point T> template<floating_point T>
@@ -325,27 +310,16 @@ namespace BAN::Math
template<floating_point T> template<floating_point T>
inline constexpr T sqrt(T x) inline constexpr T sqrt(T x)
{ {
if constexpr(BAN::is_same_v<T, float>) asm("fsqrt" : "+t"(x));
{ return x;
using v4sf = float __attribute__((vector_size(16)));
return __builtin_ia32_sqrtss((v4sf) { x, 0.0f, 0.0f, 0.0f })[0];
}
else if constexpr(BAN::is_same_v<T, double>)
{
using v2df = double __attribute__((vector_size(16)));
return __builtin_ia32_sqrtsd((v2df) { x, 0.0 })[0];
}
else if constexpr(BAN::is_same_v<T, long double>)
{
asm("fsqrt" : "+t"(x));
return x;
}
} }
template<floating_point T> template<floating_point T>
inline constexpr T cbrt(T value) inline constexpr T cbrt(T value)
{ {
return pow<T>(value, (T)1.0 / (T)3.0); if (value == 0.0)
return 0.0;
return pow<T>(value, 1.0 / 3.0);
} }
template<floating_point T> template<floating_point T>
@@ -372,21 +346,30 @@ namespace BAN::Math
inline constexpr T tan(T x) inline constexpr T tan(T x)
{ {
T one, ret; T one, ret;
asm("fptan" : "=t"(one), "=u"(ret) : "0"(x)); asm(
"fptan"
: "=t"(one), "=u"(ret)
: "0"(x)
);
return ret; return ret;
} }
template<floating_point T> template<floating_point T>
inline constexpr T atan2(T y, T x) inline constexpr T atan2(T y, T x)
{ {
asm("fpatan" : "+t"(x) : "u"(y) : "st(1)"); asm(
"fpatan"
: "+t"(x)
: "u"(y)
: "st(1)"
);
return x; return x;
} }
template<floating_point T> template<floating_point T>
inline constexpr T atan(T x) inline constexpr T atan(T x)
{ {
return atan2<T>(x, (T)1.0); return atan2<T>(x, 1.0);
} }
template<floating_point T> template<floating_point T>
@@ -395,10 +378,10 @@ namespace BAN::Math
if (x == (T)0.0) if (x == (T)0.0)
return (T)0.0; return (T)0.0;
if (x == (T)1.0) if (x == (T)1.0)
return +numbers::pi_v<T> / (T)2.0; return numbers::pi_v<T> / (T)2.0;
if (x == (T)-1.0) if (x == (T)-1.0)
return -numbers::pi_v<T> / (T)2.0; return -numbers::pi_v<T> / (T)2.0;
return (T)2.0 * atan<T>(x / ((T)1.0 + sqrt<T>((T)1.0 - x * x))); return (T)2.0 * atan<T>(x / (T(1.0) + sqrt<T>((T)1.0 - x * x)));
} }
template<floating_point T> template<floating_point T>
@@ -428,7 +411,7 @@ namespace BAN::Math
template<floating_point T> template<floating_point T>
inline constexpr T tanh(T x) inline constexpr T tanh(T x)
{ {
const T exp_px = exp<T>(+x); const T exp_px = exp<T>(x);
const T exp_nx = exp<T>(-x); const T exp_nx = exp<T>(-x);
return (exp_px - exp_nx) / (exp_px + exp_nx); return (exp_px - exp_nx) / (exp_px + exp_nx);
} }
@@ -457,9 +440,4 @@ namespace BAN::Math
return sqrt<T>(x * x + y * y); return sqrt<T>(x * x + y * y);
} }
#ifdef BAN_MATH_POP_OPTIONS
#undef BAN_MATH_POP_OPTIONS
#pragma GCC pop_options
#endif
} }

View File

@@ -9,12 +9,10 @@
namespace BAN namespace BAN
{ {
#if defined(__is_kernel) #if defined(__is_kernel)
static constexpr void*(*allocator)(size_t) = kmalloc; static constexpr void*(&allocator)(size_t) = kmalloc;
static constexpr void*(*reallocator)(void*, size_t) = nullptr; static constexpr void(&deallocator)(void*) = kfree;
static constexpr void(*deallocator)(void*) = kfree;
#else #else
static constexpr void*(*allocator)(size_t) = malloc; static constexpr void*(&allocator)(size_t) = malloc;
static constexpr void*(*reallocator)(void*, size_t) = realloc; static constexpr void(&deallocator)(void*) = free;
static constexpr void(*deallocator)(void*) = free;
#endif #endif
} }

View File

@@ -1,64 +0,0 @@
#pragma once
#include "BAN/Errors.h"
#include <BAN/Vector.h>
#include <BAN/Heap.h>
namespace BAN
{
template<typename T, typename Comp = less<T>>
class PriorityQueue
{
public:
PriorityQueue() = default;
PriorityQueue(Comp comp)
: m_comp(comp)
{ }
ErrorOr<void> push(const T& value)
{
TRY(m_data.push_back(value));
push_heap(m_data.begin(), m_data.end());
return {};
}
ErrorOr<void> push(T&& value)
{
TRY(m_data.push_back(move(value)));
push_heap(m_data.begin(), m_data.end());
return {};
}
template<typename... Args>
ErrorOr<void> emplace(Args&&... args) requires is_constructible_v<T, Args...>
{
TRY(m_data.emplace_back(forward<Args>(args)...));
push_heap(m_data.begin(), m_data.end());
return {};
}
void pop()
{
pop_heap(m_data.begin(), m_data.end());
m_data.pop_back();
}
BAN::ErrorOr<void> reserve(Vector<T>::size_type size)
{
return m_data.reserve(size);
}
T& top() { return m_data.front(); }
const T& top() const { return m_data.front(); }
bool empty() const { return m_data.empty(); }
Vector<T>::size_type size() const { return m_data.size(); }
Vector<T>::size_type capacity() const { return m_data.capacity(); }
private:
Comp m_comp;
Vector<T> m_data;
};
}

View File

@@ -1,6 +1,5 @@
#pragma once #pragma once
#include <BAN/Heap.h>
#include <BAN/Math.h> #include <BAN/Math.h>
#include <BAN/Swap.h> #include <BAN/Swap.h>
#include <BAN/Traits.h> #include <BAN/Traits.h>
@@ -9,7 +8,7 @@
namespace BAN::sort namespace BAN::sort
{ {
template<typename It, typename Comp = less<it_value_type_t<It>>> template<typename It, typename Comp = less<typename It::value_type>>
void exchange_sort(It begin, It end, Comp comp = {}) void exchange_sort(It begin, It end, Comp comp = {})
{ {
for (It lhs = begin; lhs != end; ++lhs) for (It lhs = begin; lhs != end; ++lhs)
@@ -43,7 +42,7 @@ namespace BAN::sort
} }
template<typename It, typename Comp = less<it_value_type_t<It>>> template<typename It, typename Comp = less<typename It::value_type>>
void quick_sort(It begin, It end, Comp comp = {}) void quick_sort(It begin, It end, Comp comp = {})
{ {
if (distance(begin, end) <= 1) if (distance(begin, end) <= 1)
@@ -53,14 +52,14 @@ namespace BAN::sort
quick_sort(++mid, end, comp); quick_sort(++mid, end, comp);
} }
template<typename It, typename Comp = less<it_value_type_t<It>>> template<typename It, typename Comp = less<typename It::value_type>>
void insertion_sort(It begin, It end, Comp comp = {}) void insertion_sort(It begin, It end, Comp comp = {})
{ {
if (distance(begin, end) <= 1) if (distance(begin, end) <= 1)
return; return;
for (It it1 = next(begin, 1); it1 != end; ++it1) for (It it1 = next(begin, 1); it1 != end; ++it1)
{ {
auto x = move(*it1); typename It::value_type x = move(*it1);
It it2 = it1; It it2 = it1;
for (; it2 != begin && comp(x, *prev(it2, 1)); --it2) for (; it2 != begin && comp(x, *prev(it2, 1)); --it2)
*it2 = move(*prev(it2, 1)); *it2 = move(*prev(it2, 1));
@@ -68,7 +67,83 @@ namespace BAN::sort
} }
} }
template<typename It, typename Comp = less<it_value_type_t<It>>> namespace detail
{
template<typename It, typename Comp>
void push_heap(It begin, size_t hole_index, size_t top_index, typename It::value_type value, Comp comp)
{
size_t parent = (hole_index - 1) / 2;
while (hole_index > top_index && comp(*next(begin, parent), value))
{
*next(begin, hole_index) = move(*next(begin, parent));
hole_index = parent;
parent = (hole_index - 1) / 2;
}
*next(begin, hole_index) = move(value);
}
template<typename It, typename Comp>
void adjust_heap(It begin, size_t hole_index, size_t len, typename It::value_type value, Comp comp)
{
const size_t top_index = hole_index;
size_t child = hole_index;
while (child < (len - 1) / 2)
{
child = 2 * (child + 1);
if (comp(*next(begin, child), *next(begin, child - 1)))
child--;
*next(begin, hole_index) = move(*next(begin, child));
hole_index = child;
}
if (len % 2 == 0 && child == (len - 2) / 2)
{
child = 2 * (child + 1);
*next(begin, hole_index) = move(*next(begin, child - 1));
hole_index = child - 1;
}
push_heap(begin, hole_index, top_index, move(value), comp);
}
}
template<typename It, typename Comp = less<typename It::value_type>>
void make_heap(It begin, It end, Comp comp = {})
{
const size_t len = distance(begin, end);
if (len <= 1)
return;
size_t parent = (len - 2) / 2;
while (true)
{
detail::adjust_heap(begin, parent, len, move(*next(begin, parent)), comp);
if (parent == 0)
break;
parent--;
}
}
template<typename It, typename Comp = less<typename It::value_type>>
void sort_heap(It begin, It end, Comp comp = {})
{
const size_t len = distance(begin, end);
if (len <= 1)
return;
size_t last = len;
while (last > 1)
{
last--;
typename It::value_type x = move(*next(begin, last));
*next(begin, last) = move(*begin);
detail::adjust_heap(begin, 0, last, move(x), comp);
}
}
template<typename It, typename Comp = less<typename It::value_type>>
void heap_sort(It begin, It end, Comp comp = {}) void heap_sort(It begin, It end, Comp comp = {})
{ {
make_heap(begin, end, comp); make_heap(begin, end, comp);
@@ -92,7 +167,7 @@ namespace BAN::sort
} }
template<typename It, typename Comp = less<it_value_type_t<It>>> template<typename It, typename Comp = less<typename It::value_type>>
void intro_sort(It begin, It end, Comp comp = {}) void intro_sort(It begin, It end, Comp comp = {})
{ {
const size_t len = distance(begin, end); const size_t len = distance(begin, end);
@@ -115,10 +190,10 @@ namespace BAN::sort
} }
template<typename It, size_t radix = 256> template<typename It, size_t radix = 256>
requires is_unsigned_v<it_value_type_t<It>> && (radix > 0 && (radix & (radix - 1)) == 0) requires is_unsigned_v<typename It::value_type> && (radix > 0 && (radix & (radix - 1)) == 0)
BAN::ErrorOr<void> radix_sort(It begin, It end) BAN::ErrorOr<void> radix_sort(It begin, It end)
{ {
using value_type = it_value_type_t<It>; using value_type = typename It::value_type;
const size_t len = distance(begin, end); const size_t len = distance(begin, end);
if (len <= 1) if (len <= 1)
@@ -156,7 +231,7 @@ namespace BAN::sort
return {}; return {};
} }
template<typename It, typename Comp = less<it_value_type_t<It>>> template<typename It, typename Comp = less<typename It::value_type>>
void sort(It begin, It end, Comp comp = {}) void sort(It begin, It end, Comp comp = {})
{ {
return intro_sort(begin, end, comp); return intro_sort(begin, end, comp);

View File

@@ -69,6 +69,7 @@ namespace BAN
value_type* data() const value_type* data() const
{ {
ASSERT(m_data);
return m_data; return m_data;
} }
@@ -83,6 +84,7 @@ namespace BAN
Span slice(size_type start, size_type length = ~size_type(0)) const Span slice(size_type start, size_type length = ~size_type(0)) const
{ {
ASSERT(m_data);
ASSERT(start <= m_size); ASSERT(start <= m_size);
if (length == ~size_type(0)) if (length == ~size_type(0))
length = m_size - start; length = m_size - start;

View File

@@ -14,7 +14,6 @@ namespace BAN
{ {
public: public:
using size_type = size_t; using size_type = size_t;
using value_type = char;
using iterator = IteratorSimple<char, String>; using iterator = IteratorSimple<char, String>;
using const_iterator = ConstIteratorSimple<char, String>; using const_iterator = ConstIteratorSimple<char, String>;
static constexpr size_type sso_capacity = 15; static constexpr size_type sso_capacity = 15;
@@ -353,9 +352,10 @@ namespace BAN::Formatter
{ {
template<typename F> template<typename F>
void print_argument(F putc, const String& string, const ValueFormat& format) void print_argument(F putc, const String& string, const ValueFormat&)
{ {
print_argument(putc, string.sv(), format); for (String::size_type i = 0; i < string.size(); i++)
putc(string[i]);
} }
} }

View File

@@ -14,7 +14,6 @@ namespace BAN
{ {
public: public:
using size_type = size_t; using size_type = size_t;
using value_type = char;
using const_iterator = ConstIteratorSimple<char, StringView>; using const_iterator = ConstIteratorSimple<char, StringView>;
public: public:
@@ -22,8 +21,7 @@ namespace BAN
constexpr StringView(const char* string, size_type len = -1) constexpr StringView(const char* string, size_type len = -1)
{ {
if (len == size_type(-1)) if (len == size_type(-1))
for (len = 0; string[len];) len = strlen(string);
len++;
m_data = string; m_data = string;
m_size = len; m_size = len;
} }
@@ -247,12 +245,10 @@ namespace BAN::Formatter
{ {
template<typename F> template<typename F>
void print_argument(F putc, const StringView& sv, const ValueFormat& format) void print_argument(F putc, const StringView& sv, const ValueFormat&)
{ {
for (StringView::size_type i = 0; i < sv.size(); i++) for (StringView::size_type i = 0; i < sv.size(); i++)
putc(sv[i]); putc(sv[i]);
for (int i = sv.size(); i < format.fill; i++)
putc(' ');
} }
} }

View File

@@ -61,9 +61,6 @@ namespace BAN
template<typename T> struct is_move_constructible { static constexpr bool value = is_constructible_v<T, T&&>; }; template<typename T> struct is_move_constructible { static constexpr bool value = is_constructible_v<T, T&&>; };
template<typename T> inline constexpr bool is_move_constructible_v = is_move_constructible<T>::value; template<typename T> inline constexpr bool is_move_constructible_v = is_move_constructible<T>::value;
template<typename T> struct is_trivially_copyable { static constexpr bool value = __is_trivially_copyable(T); };
template<typename T> inline constexpr bool is_trivially_copyable_v = is_trivially_copyable<T>::value;
template<typename T> struct is_integral { static constexpr bool value = requires (T t, T* p, void (*f)(T)) { reinterpret_cast<T>(t); f(0); p + t; }; }; template<typename T> struct is_integral { static constexpr bool value = requires (T t, T* p, void (*f)(T)) { reinterpret_cast<T>(t); f(0); p + t; }; };
template<typename T> inline constexpr bool is_integral_v = is_integral<T>::value; template<typename T> inline constexpr bool is_integral_v = is_integral<T>::value;
template<typename T> concept integral = is_integral_v<T>; template<typename T> concept integral = is_integral_v<T>;
@@ -142,10 +139,6 @@ namespace BAN
template<typename T> using make_signed_t = typename make_signed<T>::type; template<typename T> using make_signed_t = typename make_signed<T>::type;
#undef __BAN_TRAITS_MAKE_SIGNED_CV #undef __BAN_TRAITS_MAKE_SIGNED_CV
template<typename T> struct it_value_type { using value_type = T::value_type; };
template<typename T> struct it_value_type<T*> { using value_type = T; };
template<typename T> using it_value_type_t = typename it_value_type<T>::value_type;
template<typename T> struct less { constexpr bool operator()(const T& lhs, const T& rhs) const { return lhs < rhs; } }; template<typename T> struct less { constexpr bool operator()(const T& lhs, const T& rhs) const { return lhs < rhs; } };
template<typename T> struct equal { constexpr bool operator()(const T& lhs, const T& rhs) const { return lhs == rhs; } }; template<typename T> struct equal { constexpr bool operator()(const T& lhs, const T& rhs) const { return lhs == rhs; } };
template<typename T> struct greater { constexpr bool operator()(const T& lhs, const T& rhs) const { return lhs > rhs; } }; template<typename T> struct greater { constexpr bool operator()(const T& lhs, const T& rhs) const { return lhs > rhs; } };

View File

@@ -18,7 +18,7 @@ namespace BAN::UTF8
return 3; return 3;
if ((first_byte & 0xF8) == 0xF0) if ((first_byte & 0xF8) == 0xF0)
return 4; return 4;
return UTF8::invalid; return 0;
} }
template<typename T> requires (sizeof(T) == 1) template<typename T> requires (sizeof(T) == 1)

View File

@@ -126,16 +126,14 @@ namespace BAN
Variant(Variant&& other) Variant(Variant&& other)
: m_index(other.m_index) : m_index(other.m_index)
{ {
if (other.has_value()) detail::move_construct<Ts...>(other.m_index, other.m_storage, m_storage);
detail::move_construct<Ts...>(other.m_index, other.m_storage, m_storage);
other.clear(); other.clear();
} }
Variant(const Variant& other) Variant(const Variant& other)
: m_index(other.m_index) : m_index(other.m_index)
{ {
if (other.has_value()) detail::copy_construct<Ts...>(other.m_index, other.m_storage, m_storage);
detail::copy_construct<Ts...>(other.m_index, other.m_storage, m_storage);
} }
template<typename T> template<typename T>
@@ -159,13 +157,12 @@ namespace BAN
Variant& operator=(Variant&& other) Variant& operator=(Variant&& other)
{ {
if (m_index == other.m_index && m_index != invalid_index()) if (m_index == other.m_index)
detail::move_assign<Ts...>(m_index, other.m_storage, m_storage); detail::move_assign<Ts...>(m_index, other.m_storage, m_storage);
else else
{ {
clear(); clear();
if (other.has_value()) detail::move_construct<Ts...>(other.m_index, other.m_storage, m_storage);
detail::move_construct<Ts...>(other.m_index, other.m_storage, m_storage);
m_index = other.m_index; m_index = other.m_index;
} }
other.clear(); other.clear();
@@ -174,13 +171,12 @@ namespace BAN
Variant& operator=(const Variant& other) Variant& operator=(const Variant& other)
{ {
if (m_index == other.m_index && m_index != invalid_index()) if (m_index == other.m_index)
detail::copy_assign<Ts...>(m_index, other.m_storage, m_storage); detail::copy_assign<Ts...>(m_index, other.m_storage, m_storage);
else else
{ {
clear(); clear();
if (other.has_value()) detail::copy_construct<Ts...>(other.m_index, other.m_storage, m_storage);
detail::copy_construct<Ts...>(other.m_index, other.m_storage, m_storage);
m_index = other.m_index; m_index = other.m_index;
} }
return *this; return *this;

View File

@@ -56,7 +56,7 @@ namespace BAN
bool contains(const T&) const; bool contains(const T&) const;
Span<T> span() { return Span(m_data, m_size); } Span<T> span() { return Span(m_data, m_size); }
Span<const T> span() const { return Span(m_data, m_size); } const Span<T> span() const { return Span(m_data, m_size); }
const T& operator[](size_type) const; const T& operator[](size_type) const;
T& operator[](size_type); T& operator[](size_type);
@@ -381,46 +381,19 @@ namespace BAN
template<typename T> template<typename T>
ErrorOr<void> Vector<T>::ensure_capacity(size_type size) ErrorOr<void> Vector<T>::ensure_capacity(size_type size)
{ {
static_assert(alignof(T) <= alignof(max_align_t), "over aligned types not supported");
if (m_capacity >= size) if (m_capacity >= size)
return {}; return {};
size_type new_cap = BAN::Math::max<size_type>(size, m_capacity * 2);
const size_type new_cap = BAN::Math::max<size_type>(size, m_capacity * 2); T* new_data = (T*)BAN::allocator(new_cap * sizeof(T));
if (new_data == nullptr)
if constexpr (BAN::is_trivially_copyable_v<T>) return Error::from_errno(ENOMEM);
for (size_type i = 0; i < m_size; i++)
{ {
if constexpr (BAN::reallocator) new (new_data + i) T(move(m_data[i]));
{ m_data[i].~T();
auto* new_data = static_cast<T*>(BAN::reallocator(m_data, new_cap * sizeof(T)));
if (new_data == nullptr)
return Error::from_errno(ENOMEM);
m_data = new_data;
}
else
{
auto* new_data = static_cast<T*>(BAN::allocator(new_cap * sizeof(T)));
if (new_data == nullptr)
return Error::from_errno(ENOMEM);
memcpy(new_data, m_data, m_size * sizeof(T));
BAN::deallocator(m_data);
m_data = new_data;
}
} }
else BAN::deallocator(m_data);
{ m_data = new_data;
auto* new_data = static_cast<T*>(BAN::allocator(new_cap * sizeof(T)));
if (new_data == nullptr)
return Error::from_errno(ENOMEM);
for (size_type i = 0; i < m_size; i++)
{
new (new_data + i) T(move(m_data[i]));
m_data[i].~T();
}
BAN::deallocator(m_data);
m_data = new_data;
}
m_capacity = new_cap; m_capacity = new_cap;
return {}; return {};
} }

View File

@@ -20,7 +20,7 @@ namespace BAN
class WeakLink : public RefCounted<WeakLink<T>> class WeakLink : public RefCounted<WeakLink<T>>
{ {
public: public:
RefPtr<T> try_lock() const RefPtr<T> try_lock()
{ {
#if __is_kernel #if __is_kernel
Kernel::SpinLockGuard _(m_weak_lock); Kernel::SpinLockGuard _(m_weak_lock);
@@ -44,7 +44,7 @@ namespace BAN
private: private:
T* m_ptr; T* m_ptr;
#if __is_kernel #if __is_kernel
mutable Kernel::SpinLock m_weak_lock; Kernel::SpinLock m_weak_lock;
#endif #endif
friend class RefPtr<WeakLink<T>>; friend class RefPtr<WeakLink<T>>;
}; };
@@ -99,7 +99,7 @@ namespace BAN
return *this; return *this;
} }
RefPtr<T> lock() const RefPtr<T> lock()
{ {
if (m_link) if (m_link)
return m_link->try_lock(); return m_link->try_lock();

View File

@@ -29,12 +29,12 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# include headers of ${library} to ${target} # include headers of ${library} to ${target}
function(banan_include_headers target library) function(banan_include_headers target library)
target_include_directories(${target} PUBLIC $<TARGET_PROPERTY:${library},SOURCE_DIR>/include) target_include_directories(${target} PRIVATE $<TARGET_PROPERTY:${library},SOURCE_DIR>/include)
endfunction() endfunction()
# include headers and link ${library} to ${target} # include headers and link ${library} to ${target}
function(banan_link_library target library) function(banan_link_library target library)
target_link_libraries(${target} PUBLIC ${library}) target_link_libraries(${target} PRIVATE ${library})
banan_include_headers(${target} ${library}) banan_include_headers(${target} ${library})
endfunction() endfunction()

View File

@@ -23,7 +23,7 @@ If you want to try out DOOM, you should first enter the GUI environment using th
- [x] Basic graphical environment - [x] Basic graphical environment
- [x] Terminal emulator - [x] Terminal emulator
- [x] Status bar - [x] Status bar
- [x] Program launcher - [ ] Program launcher
- [ ] Some nice apps - [ ] Some nice apps
- [x] ELF dynamic linking - [x] ELF dynamic linking
- [x] copy-on-write memory - [x] copy-on-write memory
@@ -118,8 +118,6 @@ To change the bootloader you can set environment variable BANAN\_BOOTLOADER; sup
To run with UEFI set environment variable BANAN\_UEFI\_BOOT=1. You will also have to set OVMF\_PATH to the correct OVMF (default */usr/share/ovmf/x64/OVMF.fd*). To run with UEFI set environment variable BANAN\_UEFI\_BOOT=1. You will also have to set OVMF\_PATH to the correct OVMF (default */usr/share/ovmf/x64/OVMF.fd*).
To build an image with no physical root filesystem, but an initrd set environment variable BANAN\_INITRD=1. This can be used when testing on hardware with unsupported USB controller.
If you have corrupted your disk image or want to create new one, you can either manually delete *build/banan-os.img* and build system will automatically create you a new one or you can run the following command. If you have corrupted your disk image or want to create new one, you can either manually delete *build/banan-os.img* and build system will automatically create you a new one or you can run the following command.
```sh ```sh
./bos image-full ./bos image-full

Binary file not shown.

View File

@@ -1,16 +1,11 @@
set(KERNEL_SOURCES set(KERNEL_SOURCES
font/prefs.psf.o font/prefs.psf.o
kernel/ACPI/ACPI.cpp kernel/ACPI/ACPI.cpp
kernel/ACPI/BatterySystem.cpp
kernel/ACPI/AML/Namespace.cpp kernel/ACPI/AML/Namespace.cpp
kernel/ACPI/AML/Node.cpp kernel/ACPI/AML/Node.cpp
kernel/ACPI/AML/OpRegion.cpp kernel/ACPI/AML/OpRegion.cpp
kernel/ACPI/BatterySystem.cpp
kernel/ACPI/EmbeddedController.cpp
kernel/APIC.cpp kernel/APIC.cpp
kernel/Audio/AC97/Controller.cpp
kernel/Audio/Controller.cpp
kernel/Audio/HDAudio/AudioFunctionGroup.cpp
kernel/Audio/HDAudio/Controller.cpp
kernel/BootInfo.cpp kernel/BootInfo.cpp
kernel/CPUID.cpp kernel/CPUID.cpp
kernel/Credentials.cpp kernel/Credentials.cpp
@@ -22,10 +17,8 @@ set(KERNEL_SOURCES
kernel/Device/RandomDevice.cpp kernel/Device/RandomDevice.cpp
kernel/Device/ZeroDevice.cpp kernel/Device/ZeroDevice.cpp
kernel/ELF.cpp kernel/ELF.cpp
kernel/Epoll.cpp
kernel/Errors.cpp kernel/Errors.cpp
kernel/FS/DevFS/FileSystem.cpp kernel/FS/DevFS/FileSystem.cpp
kernel/FS/EventFD.cpp
kernel/FS/Ext2/FileSystem.cpp kernel/FS/Ext2/FileSystem.cpp
kernel/FS/Ext2/Inode.cpp kernel/FS/Ext2/Inode.cpp
kernel/FS/FAT/FileSystem.cpp kernel/FS/FAT/FileSystem.cpp
@@ -37,7 +30,6 @@ set(KERNEL_SOURCES
kernel/FS/ProcFS/Inode.cpp kernel/FS/ProcFS/Inode.cpp
kernel/FS/TmpFS/FileSystem.cpp kernel/FS/TmpFS/FileSystem.cpp
kernel/FS/TmpFS/Inode.cpp kernel/FS/TmpFS/Inode.cpp
kernel/FS/USTARModule.cpp
kernel/FS/VirtualFileSystem.cpp kernel/FS/VirtualFileSystem.cpp
kernel/GDT.cpp kernel/GDT.cpp
kernel/IDT.cpp kernel/IDT.cpp
@@ -50,8 +42,6 @@ set(KERNEL_SOURCES
kernel/Interruptable.cpp kernel/Interruptable.cpp
kernel/InterruptController.cpp kernel/InterruptController.cpp
kernel/kernel.cpp kernel/kernel.cpp
kernel/Lock/SpinLock.cpp
kernel/Memory/ByteRingBuffer.cpp
kernel/Memory/DMARegion.cpp kernel/Memory/DMARegion.cpp
kernel/Memory/FileBackedRegion.cpp kernel/Memory/FileBackedRegion.cpp
kernel/Memory/Heap.cpp kernel/Memory/Heap.cpp
@@ -65,7 +55,6 @@ set(KERNEL_SOURCES
kernel/Networking/E1000/E1000.cpp kernel/Networking/E1000/E1000.cpp
kernel/Networking/E1000/E1000E.cpp kernel/Networking/E1000/E1000E.cpp
kernel/Networking/IPv4Layer.cpp kernel/Networking/IPv4Layer.cpp
kernel/Networking/Loopback.cpp
kernel/Networking/NetworkInterface.cpp kernel/Networking/NetworkInterface.cpp
kernel/Networking/NetworkLayer.cpp kernel/Networking/NetworkLayer.cpp
kernel/Networking/NetworkManager.cpp kernel/Networking/NetworkManager.cpp
@@ -82,6 +71,7 @@ set(KERNEL_SOURCES
kernel/Processor.cpp kernel/Processor.cpp
kernel/Random.cpp kernel/Random.cpp
kernel/Scheduler.cpp kernel/Scheduler.cpp
kernel/ThreadBlocker.cpp
kernel/SSP.cpp kernel/SSP.cpp
kernel/Storage/ATA/AHCI/Controller.cpp kernel/Storage/ATA/AHCI/Controller.cpp
kernel/Storage/ATA/AHCI/Device.cpp kernel/Storage/ATA/AHCI/Device.cpp
@@ -104,7 +94,6 @@ set(KERNEL_SOURCES
kernel/Terminal/TTY.cpp kernel/Terminal/TTY.cpp
kernel/Terminal/VirtualTTY.cpp kernel/Terminal/VirtualTTY.cpp
kernel/Thread.cpp kernel/Thread.cpp
kernel/ThreadBlocker.cpp
kernel/Timer/HPET.cpp kernel/Timer/HPET.cpp
kernel/Timer/PIT.cpp kernel/Timer/PIT.cpp
kernel/Timer/RTC.cpp kernel/Timer/RTC.cpp
@@ -112,7 +101,6 @@ set(KERNEL_SOURCES
kernel/USB/Controller.cpp kernel/USB/Controller.cpp
kernel/USB/Device.cpp kernel/USB/Device.cpp
kernel/USB/HID/HIDDriver.cpp kernel/USB/HID/HIDDriver.cpp
kernel/USB/HID/Joystick.cpp
kernel/USB/HID/Keyboard.cpp kernel/USB/HID/Keyboard.cpp
kernel/USB/HID/Mouse.cpp kernel/USB/HID/Mouse.cpp
kernel/USB/Hub/HubDriver.cpp kernel/USB/Hub/HubDriver.cpp
@@ -139,8 +127,6 @@ if("${BANAN_ARCH}" STREQUAL "x86_64")
arch/x86_64/Signal.S arch/x86_64/Signal.S
arch/x86_64/Syscall.S arch/x86_64/Syscall.S
arch/x86_64/Thread.S arch/x86_64/Thread.S
arch/x86_64/User.S
arch/x86_64/Yield.S
) )
elseif("${BANAN_ARCH}" STREQUAL "i686") elseif("${BANAN_ARCH}" STREQUAL "i686")
set(KERNEL_SOURCES set(KERNEL_SOURCES
@@ -151,8 +137,6 @@ elseif("${BANAN_ARCH}" STREQUAL "i686")
arch/i686/Signal.S arch/i686/Signal.S
arch/i686/Syscall.S arch/i686/Syscall.S
arch/i686/Thread.S arch/i686/Thread.S
arch/i686/User.S
arch/i686/Yield.S
) )
else() else()
message(FATAL_ERROR "unsupported architecure ${BANAN_ARCH}") message(FATAL_ERROR "unsupported architecure ${BANAN_ARCH}")
@@ -174,12 +158,6 @@ set(KLIBC_SOURCES
../userspace/libraries/LibC/arch/${BANAN_ARCH}/string.S ../userspace/libraries/LibC/arch/${BANAN_ARCH}/string.S
) )
set(LIBDEFLATE_SOURCE
../userspace/libraries/LibDEFLATE/Compressor.cpp
../userspace/libraries/LibDEFLATE/Decompressor.cpp
../userspace/libraries/LibDEFLATE/HuffmanTree.cpp
)
set(LIBFONT_SOURCES set(LIBFONT_SOURCES
../userspace/libraries/LibFont/Font.cpp ../userspace/libraries/LibFont/Font.cpp
../userspace/libraries/LibFont/PSF.cpp ../userspace/libraries/LibFont/PSF.cpp
@@ -190,25 +168,18 @@ set(LIBINPUT_SOURCE
../userspace/libraries/LibInput/KeyEvent.cpp ../userspace/libraries/LibInput/KeyEvent.cpp
) )
set(LIBQR_SOURCE
../userspace/libraries/LibQR/QRCode.cpp
)
set(KERNEL_SOURCES set(KERNEL_SOURCES
${KERNEL_SOURCES} ${KERNEL_SOURCES}
${BAN_SOURCES} ${BAN_SOURCES}
${KLIBC_SOURCES} ${KLIBC_SOURCES}
${LIBDEFLATE_SOURCE}
${LIBFONT_SOURCES} ${LIBFONT_SOURCES}
${LIBINPUT_SOURCE} ${LIBINPUT_SOURCE}
${LIBQR_SOURCE}
) )
add_executable(kernel ${KERNEL_SOURCES}) add_executable(kernel ${KERNEL_SOURCES})
target_compile_definitions(kernel PRIVATE __is_kernel) target_compile_definitions(kernel PRIVATE __is_kernel)
target_compile_definitions(kernel PRIVATE __arch=${BANAN_ARCH}) target_compile_definitions(kernel PRIVATE __arch=${BANAN_ARCH})
target_compile_definitions(kernel PRIVATE LIBDEFLATE_AVOID_STACK=1)
target_compile_options(kernel PRIVATE target_compile_options(kernel PRIVATE
-O2 -g -O2 -g
@@ -262,11 +233,9 @@ add_custom_command(
banan_include_headers(kernel ban) banan_include_headers(kernel ban)
banan_include_headers(kernel libc) banan_include_headers(kernel libc)
banan_include_headers(kernel libdeflate)
banan_include_headers(kernel libelf)
banan_include_headers(kernel libfont) banan_include_headers(kernel libfont)
banan_include_headers(kernel libelf)
banan_include_headers(kernel libinput) banan_include_headers(kernel libinput)
banan_include_headers(kernel libqr)
banan_install_headers(kernel) banan_install_headers(kernel)
set_target_properties(kernel PROPERTIES OUTPUT_NAME banan-os.kernel) set_target_properties(kernel PROPERTIES OUTPUT_NAME banan-os.kernel)

View File

@@ -206,7 +206,6 @@ namespace Kernel
{ {
ASSERT(s_kernel); ASSERT(s_kernel);
ASSERT(paddr); ASSERT(paddr);
ASSERT(paddr % PAGE_SIZE == 0);
ASSERT(s_fast_page_lock.current_processor_has_lock()); ASSERT(s_fast_page_lock.current_processor_has_lock());
@@ -221,7 +220,7 @@ namespace Kernel
ASSERT(!(pt[pte] & Flags::Present)); ASSERT(!(pt[pte] & Flags::Present));
pt[pte] = paddr | Flags::ReadWrite | Flags::Present; pt[pte] = paddr | Flags::ReadWrite | Flags::Present;
asm volatile("invlpg (%0)" :: "r"(fast_page()) : "memory"); invalidate(fast_page(), false);
} }
void PageTable::unmap_fast_page() void PageTable::unmap_fast_page()
@@ -241,7 +240,7 @@ namespace Kernel
ASSERT(pt[pte] & Flags::Present); ASSERT(pt[pte] & Flags::Present);
pt[pte] = 0; pt[pte] = 0;
asm volatile("invlpg (%0)" :: "r"(fast_page()) : "memory"); invalidate(fast_page(), false);
} }
BAN::ErrorOr<PageTable*> PageTable::create_userspace() BAN::ErrorOr<PageTable*> PageTable::create_userspace()
@@ -314,8 +313,7 @@ namespace Kernel
.type = Processor::SMPMessage::Type::FlushTLB, .type = Processor::SMPMessage::Type::FlushTLB,
.flush_tlb = { .flush_tlb = {
.vaddr = vaddr, .vaddr = vaddr,
.page_count = 1, .page_count = 1
.page_table = vaddr < KERNEL_OFFSET ? this : nullptr,
} }
}); });
} }
@@ -344,12 +342,8 @@ namespace Kernel
uint64_t* pd = reinterpret_cast<uint64_t*>(P2V(pdpt[pdpte] & PAGE_ADDR_MASK)); uint64_t* pd = reinterpret_cast<uint64_t*>(P2V(pdpt[pdpte] & PAGE_ADDR_MASK));
uint64_t* pt = reinterpret_cast<uint64_t*>(P2V(pd[pde] & PAGE_ADDR_MASK)); uint64_t* pt = reinterpret_cast<uint64_t*>(P2V(pd[pde] & PAGE_ADDR_MASK));
const paddr_t old_paddr = pt[pte] & PAGE_ADDR_MASK;
pt[pte] = 0; pt[pte] = 0;
invalidate(vaddr, send_smp_message);
if (old_paddr != 0)
invalidate(vaddr, send_smp_message);
} }
void PageTable::unmap_range(vaddr_t vaddr, size_t size) void PageTable::unmap_range(vaddr_t vaddr, size_t size)
@@ -366,8 +360,7 @@ namespace Kernel
.type = Processor::SMPMessage::Type::FlushTLB, .type = Processor::SMPMessage::Type::FlushTLB,
.flush_tlb = { .flush_tlb = {
.vaddr = vaddr, .vaddr = vaddr,
.page_count = page_count, .page_count = page_count
.page_table = vaddr < KERNEL_OFFSET ? this : nullptr,
} }
}); });
} }
@@ -423,13 +416,9 @@ namespace Kernel
uwr_flags &= ~Flags::Present; uwr_flags &= ~Flags::Present;
uint64_t* pt = reinterpret_cast<uint64_t*>(P2V(pd[pde] & PAGE_ADDR_MASK)); uint64_t* pt = reinterpret_cast<uint64_t*>(P2V(pd[pde] & PAGE_ADDR_MASK));
const paddr_t old_paddr = pt[pte] & PAGE_ADDR_MASK;
pt[pte] = paddr | uwr_flags | extra_flags; pt[pte] = paddr | uwr_flags | extra_flags;
if (old_paddr != 0) invalidate(vaddr, send_smp_message);
invalidate(vaddr, send_smp_message);
} }
void PageTable::map_range_at(paddr_t paddr, vaddr_t vaddr, size_t size, flags_t flags, MemoryType memory_type) void PageTable::map_range_at(paddr_t paddr, vaddr_t vaddr, size_t size, flags_t flags, MemoryType memory_type)
@@ -448,8 +437,7 @@ namespace Kernel
.type = Processor::SMPMessage::Type::FlushTLB, .type = Processor::SMPMessage::Type::FlushTLB,
.flush_tlb = { .flush_tlb = {
.vaddr = vaddr, .vaddr = vaddr,
.page_count = page_count, .page_count = page_count
.page_table = vaddr < KERNEL_OFFSET ? this : nullptr,
} }
}); });
} }
@@ -508,13 +496,13 @@ namespace Kernel
return true; return true;
} }
bool PageTable::reserve_page(vaddr_t vaddr, bool only_free, bool send_smp_message) bool PageTable::reserve_page(vaddr_t vaddr, bool only_free)
{ {
SpinLockGuard _(m_lock); SpinLockGuard _(m_lock);
ASSERT(vaddr % PAGE_SIZE == 0); ASSERT(vaddr % PAGE_SIZE == 0);
if (only_free && !is_page_free(vaddr)) if (only_free && !is_page_free(vaddr))
return false; return false;
map_page_at(0, vaddr, Flags::Reserved, MemoryType::Normal, send_smp_message); map_page_at(0, vaddr, Flags::Reserved);
return true; return true;
} }
@@ -528,15 +516,7 @@ namespace Kernel
if (only_free && !is_range_free(vaddr, bytes)) if (only_free && !is_range_free(vaddr, bytes))
return false; return false;
for (size_t offset = 0; offset < bytes; offset += PAGE_SIZE) for (size_t offset = 0; offset < bytes; offset += PAGE_SIZE)
reserve_page(vaddr + offset, true, false); reserve_page(vaddr + offset);
Processor::broadcast_smp_message({
.type = Processor::SMPMessage::Type::FlushTLB,
.flush_tlb = {
.vaddr = vaddr,
.page_count = bytes / PAGE_SIZE,
.page_table = vaddr < KERNEL_OFFSET ? this : nullptr,
}
});
return true; return true;
} }

View File

@@ -2,72 +2,33 @@
// stack contains // stack contains
// return address // return address
// return stack
// return rflags
// siginfo_t
// signal number // signal number
// signal handler // signal handler
.global signal_trampoline .global signal_trampoline
signal_trampoline: signal_trampoline:
pushl %esi // gregs
pushl %edi
pushl %edx
pushl %ecx
pushl %ebx
pushl %eax
pushl %ebp pushl %ebp
movl %esp, %ebp
// FIXME: populate these pusha
xorl %eax, %eax
pushl %eax // stack
pushl %eax
pushl %eax
pushl %eax // sigset
pushl %eax
pushl %eax // link
movl %esp, %edx // ucontext movl 40(%esp), %edi
leal 60(%esp), %esi // siginfo movl 36(%esp), %eax
movl 56(%esp), %edi // signal number
movl 52(%esp), %eax // handlers
// align stack to 16 bytes // align stack to 16 bytes
movl %esp, %ebp movl %esp, %ebp
andl $-16, %esp andl $-16, %esp
subl $512, %esp subl $12, %esp
fxsave (%esp)
subl $4, %esp
pushl %edx
pushl %esi
pushl %edi pushl %edi
call *%eax call *%eax
addl $16, %esp addl $16, %esp
fxrstor (%esp)
addl $512, %esp
// restore stack // restore stack
movl %ebp, %esp movl %ebp, %esp
addl $24, %esp popa
// restore registers leave
popl %ebp addl $8, %esp
popl %eax
popl %ebx
popl %ecx
popl %edx
popl %edi
popl %esi
// skip handler, number, siginfo_t
addl $44, %esp
// restore flags
popf
movl (%esp), %esp
ret ret

View File

@@ -1,6 +1,12 @@
// arguments in EAX, EBX, ECX, EDX, ESI, EDI // arguments in EAX, EBX, ECX, EDX, ESI, EDI
.global asm_syscall_handler .global asm_syscall_handler
asm_syscall_handler: asm_syscall_handler:
# save segment registers
pushw %ds
pushw %es
pushw %fs
pushw %gs
# save general purpose registers # save general purpose registers
pushl %ebx pushl %ebx
pushl %ecx pushl %ecx
@@ -12,10 +18,13 @@ asm_syscall_handler:
# align stack # align stack
movl %esp, %ebp movl %esp, %ebp
andl $-16, %esp subl $15, %esp
andl $0xFFFFFFF0, %esp
# push arguments # push arguments
subl $8, %esp subl $4, %esp
pushl %ebp
addl $32, (%esp)
pushl %edi pushl %edi
pushl %esi pushl %esi
pushl %edx pushl %edx
@@ -35,15 +44,6 @@ asm_syscall_handler:
movl %ebp, %esp movl %ebp, %esp
# restore userspace segments
movw $(0x20 | 3), %bx
movw %bx, %ds
movw %bx, %es
movw $(0x30 | 3), %bx
movw %bx, %fs
movw $(0x38 | 3), %bx
movw %bx, %gs
# restore general purpose registers # restore general purpose registers
popl %ebp popl %ebp
popl %esi popl %esi
@@ -52,6 +52,12 @@ asm_syscall_handler:
popl %ecx popl %ecx
popl %ebx popl %ebx
# restore segment registers
popw %gs
popw %fs
popw %es
popw %ds
iret iret
.global sys_fork_trampoline .global sys_fork_trampoline

View File

@@ -31,18 +31,25 @@ start_kernel_thread:
subl $12, %esp subl $12, %esp
pushl %edi pushl %edi
call *%esi call *%esi
addl $16, %esp
.global start_userspace_thread .global start_userspace_thread
start_userspace_thread: start_userspace_thread:
call load_thread_sse
call get_thread_start_sp call get_thread_start_sp
movl %eax, %esp movl %eax, %esp
# ds, es = user data
movw $(0x20 | 3), %bx movw $(0x20 | 3), %bx
movw %bx, %ds movw %bx, %ds
movw %bx, %es movw %bx, %es
# gs = thread local
movw $(0x30 | 3), %bx movw $(0x30 | 3), %bx
movw %bx, %fs
movw $(0x38 | 3), %bx
movw %bx, %gs movw %bx, %gs
# fs = 0
xorw %bx, %bx
movw %bx, %fs
iret iret

View File

@@ -1,54 +0,0 @@
# bool safe_user_memcpy(void*, const void*, size_t)
.global safe_user_memcpy
.global safe_user_memcpy_end
.global safe_user_memcpy_fault
safe_user_memcpy:
xorl %eax, %eax
xchgl 4(%esp), %edi
xchgl 8(%esp), %esi
movl 12(%esp), %ecx
movl %edi, %edx
rep movsb
movl 4(%esp), %edi
movl 8(%esp), %esi
incl %eax
safe_user_memcpy_fault:
ret
safe_user_memcpy_end:
# bool safe_user_strncpy(void*, const void*, size_t)
.global safe_user_strncpy
.global safe_user_strncpy_end
.global safe_user_strncpy_fault
safe_user_strncpy:
xchgl 4(%esp), %edi
xchgl 8(%esp), %esi
movl 12(%esp), %ecx
testl %ecx, %ecx
jz safe_user_strncpy_fault
.safe_user_strncpy_loop:
movb (%esi), %al
movb %al, (%edi)
testb %al, %al
jz .safe_user_strncpy_done
incl %edi
incl %esi
decl %ecx
jnz .safe_user_strncpy_loop
safe_user_strncpy_fault:
xorl %eax, %eax
jmp .safe_user_strncpy_return
.safe_user_strncpy_done:
movl $1, %eax
.safe_user_strncpy_return:
movl 4(%esp), %edi
movl 8(%esp), %esi
ret
safe_user_strncpy_end:

View File

@@ -1,25 +0,0 @@
.global asm_yield_trampoline
asm_yield_trampoline:
leal 4(%esp), %ecx
movl 4(%esp), %esp
pushl -4(%ecx)
pushl %ecx
pushl %eax
pushl %ebx
pushl %esi
pushl %edi
pushl %ebp
pushl %esp
call scheduler_on_yield
addl $4, %esp
popl %ebp
popl %edi
popl %esi
popl %ebx
popl %eax
movl 4(%esp), %ecx
movl 0(%esp), %esp
jmp *%ecx

View File

@@ -14,23 +14,6 @@
# multiboot2 header # multiboot2 header
.section .multiboot, "aw" .section .multiboot, "aw"
.align 8 .align 8
multiboot_start:
.long 0x1BADB002
.long (1 << 2) # page align modules
.long -(0x1BADB002 + (1 << 2))
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long FB_WIDTH
.long FB_HEIGHT
.long FB_BPP
multiboot_end:
.align 8
multiboot2_start: multiboot2_start:
.long 0xE85250D6 .long 0xE85250D6
.long 0 .long 0
@@ -53,12 +36,6 @@ multiboot2_start:
.long 12 .long 12
.long V2P(_start) .long V2P(_start)
# page align modules
.align 8
.short 6
.short 0
.long 8
.align 8 .align 8
.short 0 .short 0
.short 0 .short 0
@@ -76,10 +53,10 @@ bananboot_start:
bananboot_end: bananboot_end:
.section .bss, "aw", @nobits .section .bss, "aw", @nobits
.global g_boot_stack_top .align 4096
g_boot_stack_bottom: boot_stack_bottom:
.skip 4096 * 4 .skip 4096 * 4
g_boot_stack_top: boot_stack_top:
.global g_kernel_cmdline .global g_kernel_cmdline
g_kernel_cmdline: g_kernel_cmdline:
@@ -184,13 +161,6 @@ enable_sse:
movl %eax, %cr4 movl %eax, %cr4
ret ret
enable_tsc:
# allow userspace to use RDTSC
movl %cr4, %ecx
andl $0xFFFFFFFB, %ecx
movl %ecx, %cr4
ret
initialize_paging: initialize_paging:
# enable PAE # enable PAE
movl %cr4, %ecx movl %cr4, %ecx
@@ -218,7 +188,7 @@ _start:
movl %ebx, V2P(bootloader_info) movl %ebx, V2P(bootloader_info)
# load boot stack # load boot stack
movl $V2P(g_boot_stack_top), %esp movl $V2P(boot_stack_top), %esp
# load boot GDT # load boot GDT
lgdt V2P(boot_gdtr) lgdt V2P(boot_gdtr)
@@ -233,11 +203,10 @@ gdt_flush:
# do processor initialization # do processor initialization
call check_requirements call check_requirements
call enable_sse call enable_sse
call enable_tsc
call initialize_paging call initialize_paging
# load higher half stack pointer # load higher half stack pointer
movl $g_boot_stack_top, %esp movl $boot_stack_top, %esp
# jump to higher half # jump to higher half
leal higher_half, %ecx leal higher_half, %ecx
@@ -310,7 +279,6 @@ ap_protected_mode:
movb $1, AP_V2P(ap_stack_loaded) movb $1, AP_V2P(ap_stack_loaded)
leal V2P(enable_sse), %ecx; call *%ecx leal V2P(enable_sse), %ecx; call *%ecx
leal V2P(enable_tsc), %ecx; call *%ecx
leal V2P(initialize_paging), %ecx; call *%ecx leal V2P(initialize_paging), %ecx; call *%ecx
# load boot gdt and enter long mode # load boot gdt and enter long mode

View File

@@ -1,33 +1,32 @@
.macro maybe_load_kernel_segments, n .macro push_userspace
testb $3, \n(%esp) pushw %gs
jz 1f; jnp 1f pushw %fs
pushw %es
pushw %ds
pushal
.endm
.macro load_kernel_segments
movw $0x10, %ax movw $0x10, %ax
movw %ax, %ds movw %ax, %ds
movw %ax, %es movw %ax, %es
movw %ax, %fs movw %ax, %fs
movw $0x28, %ax movw $0x28, %ax
movw %ax, %gs movw %ax, %gs
1:
.endm .endm
.macro maybe_load_userspace_segments, n .macro pop_userspace
testb $3, \n(%esp) popal
jz 1f; jnp 1f popw %ds
popw %es
movw $(0x20 | 3), %bx popw %fs
movw %bx, %ds popw %gs
movw %bx, %es
movw $(0x30 | 3), %bx
movw %bx, %fs
movw $(0x38 | 3), %bx
movw %bx, %gs
1:
.endm .endm
isr_stub: isr_stub:
pushal push_userspace
maybe_load_kernel_segments 44 load_kernel_segments
cld cld
movl %cr0, %eax; pushl %eax movl %cr0, %eax; pushl %eax
@@ -35,39 +34,33 @@ isr_stub:
movl %cr3, %eax; pushl %eax movl %cr3, %eax; pushl %eax
movl %cr4, %eax; pushl %eax movl %cr4, %eax; pushl %eax
movl 48(%esp), %edi // isr number movl %esp, %eax // register ptr
movl 52(%esp), %esi // error code leal 64(%esp), %ebx // interrupt stack ptr
leal 56(%esp), %edx // interrupt stack ptr movl 60(%esp), %ecx // error code
movl %esp, %ecx // register ptr movl 56(%esp), %edx // isr number
# stack frame for stack trace
leal 56(%esp), %eax
pushl (%eax)
pushl %ebp
movl %esp, %ebp movl %esp, %ebp
andl $-16, %esp andl $-16, %esp
pushl %eax
pushl %ebx
pushl %ecx pushl %ecx
pushl %edx pushl %edx
pushl %esi
pushl %edi
call cpp_isr_handler call cpp_isr_handler
movl %ebp, %esp movl %ebp, %esp
addl $24, %esp addl $16, %esp
maybe_load_userspace_segments 44 pop_userspace
popal
addl $8, %esp addl $8, %esp
iret iret
irq_stub: irq_stub:
pushal push_userspace
maybe_load_kernel_segments 44 load_kernel_segments
cld cld
movl 32(%esp), %edi # interrupt number movl 40(%esp), %edi # interrupt number
movl %esp, %ebp movl %esp, %ebp
andl $-16, %esp andl $-16, %esp
@@ -78,15 +71,36 @@ irq_stub:
movl %ebp, %esp movl %ebp, %esp
maybe_load_userspace_segments 44 pop_userspace
popal
addl $8, %esp addl $8, %esp
iret iret
.global asm_yield_handler
asm_yield_handler:
# This can only be called from kernel, so no segment saving is needed
pushal
cld
leal 32(%esp), %edi # interrupt stack ptr
movl %esp, %esi # interrupt registers ptr
movl %esp, %ebp
andl $-16, %esp
subl $8, %esp
pushl %esi
pushl %edi
call cpp_yield_handler
movl %ebp, %esp
popal
iret
.global asm_ipi_handler .global asm_ipi_handler
asm_ipi_handler: asm_ipi_handler:
pushal push_userspace
maybe_load_kernel_segments 36 load_kernel_segments
cld cld
movl %esp, %ebp movl %esp, %ebp
@@ -96,14 +110,13 @@ asm_ipi_handler:
movl %ebp, %esp movl %ebp, %esp
maybe_load_userspace_segments 36 pop_userspace
popal
iret iret
.global asm_timer_handler .global asm_timer_handler
asm_timer_handler: asm_timer_handler:
pushal push_userspace
maybe_load_kernel_segments 36 load_kernel_segments
cld cld
movl %esp, %ebp movl %esp, %ebp
@@ -113,8 +126,7 @@ asm_timer_handler:
movl %ebp, %esp movl %ebp, %esp
maybe_load_userspace_segments 36 pop_userspace
popal
iret iret
.macro isr n .macro isr n

View File

@@ -503,7 +503,6 @@ namespace Kernel
{ {
ASSERT(s_kernel); ASSERT(s_kernel);
ASSERT(paddr); ASSERT(paddr);
ASSERT(paddr % PAGE_SIZE == 0);
ASSERT(s_fast_page_lock.current_processor_has_lock()); ASSERT(s_fast_page_lock.current_processor_has_lock());
@@ -521,7 +520,7 @@ namespace Kernel
ASSERT(!(pt[pte] & Flags::Present)); ASSERT(!(pt[pte] & Flags::Present));
pt[pte] = paddr | Flags::ReadWrite | Flags::Present; pt[pte] = paddr | Flags::ReadWrite | Flags::Present;
asm volatile("invlpg (%0)" :: "r"(fast_page()) : "memory"); invalidate(fast_page(), false);
} }
void PageTable::unmap_fast_page() void PageTable::unmap_fast_page()
@@ -544,7 +543,7 @@ namespace Kernel
ASSERT(pt[pte] & Flags::Present); ASSERT(pt[pte] & Flags::Present);
pt[pte] = 0; pt[pte] = 0;
asm volatile("invlpg (%0)" :: "r"(fast_page()) : "memory"); invalidate(fast_page(), false);
} }
BAN::ErrorOr<PageTable*> PageTable::create_userspace() BAN::ErrorOr<PageTable*> PageTable::create_userspace()
@@ -623,8 +622,7 @@ namespace Kernel
.type = Processor::SMPMessage::Type::FlushTLB, .type = Processor::SMPMessage::Type::FlushTLB,
.flush_tlb = { .flush_tlb = {
.vaddr = vaddr, .vaddr = vaddr,
.page_count = 1, .page_count = 1
.page_table = vaddr < KERNEL_OFFSET ? this : nullptr,
} }
}); });
} }
@@ -659,12 +657,8 @@ namespace Kernel
uint64_t* pd = P2V(pdpt[pdpte] & s_page_addr_mask); uint64_t* pd = P2V(pdpt[pdpte] & s_page_addr_mask);
uint64_t* pt = P2V(pd[pde] & s_page_addr_mask); uint64_t* pt = P2V(pd[pde] & s_page_addr_mask);
const paddr_t old_paddr = pt[pte] & PAGE_ADDR_MASK;
pt[pte] = 0; pt[pte] = 0;
invalidate(vaddr, send_smp_message);
if (old_paddr != 0)
invalidate(vaddr, send_smp_message);
} }
void PageTable::unmap_range(vaddr_t vaddr, size_t size) void PageTable::unmap_range(vaddr_t vaddr, size_t size)
@@ -681,8 +675,7 @@ namespace Kernel
.type = Processor::SMPMessage::Type::FlushTLB, .type = Processor::SMPMessage::Type::FlushTLB,
.flush_tlb = { .flush_tlb = {
.vaddr = vaddr, .vaddr = vaddr,
.page_count = page_count, .page_count = page_count
.page_table = vaddr < KERNEL_OFFSET ? this : nullptr,
} }
}); });
} }
@@ -748,12 +741,9 @@ namespace Kernel
if (!(flags & Flags::Present)) if (!(flags & Flags::Present))
uwr_flags &= ~Flags::Present; uwr_flags &= ~Flags::Present;
const paddr_t old_paddr = pt[pte] & PAGE_ADDR_MASK;
pt[pte] = paddr | uwr_flags | extra_flags; pt[pte] = paddr | uwr_flags | extra_flags;
if (old_paddr != 0) invalidate(vaddr, send_smp_message);
invalidate(vaddr, send_smp_message);
} }
void PageTable::map_range_at(paddr_t paddr, vaddr_t vaddr, size_t size, flags_t flags, MemoryType memory_type) void PageTable::map_range_at(paddr_t paddr, vaddr_t vaddr, size_t size, flags_t flags, MemoryType memory_type)
@@ -774,8 +764,7 @@ namespace Kernel
.type = Processor::SMPMessage::Type::FlushTLB, .type = Processor::SMPMessage::Type::FlushTLB,
.flush_tlb = { .flush_tlb = {
.vaddr = vaddr, .vaddr = vaddr,
.page_count = page_count, .page_count = page_count
.page_table = vaddr < KERNEL_OFFSET ? this : nullptr,
} }
}); });
} }
@@ -824,13 +813,13 @@ namespace Kernel
return page_data & s_page_addr_mask; return page_data & s_page_addr_mask;
} }
bool PageTable::reserve_page(vaddr_t vaddr, bool only_free, bool send_smp_message) bool PageTable::reserve_page(vaddr_t vaddr, bool only_free)
{ {
SpinLockGuard _(m_lock); SpinLockGuard _(m_lock);
ASSERT(vaddr % PAGE_SIZE == 0); ASSERT(vaddr % PAGE_SIZE == 0);
if (only_free && !is_page_free(vaddr)) if (only_free && !is_page_free(vaddr))
return false; return false;
map_page_at(0, vaddr, Flags::Reserved, MemoryType::Normal, send_smp_message); map_page_at(0, vaddr, Flags::Reserved);
return true; return true;
} }
@@ -844,15 +833,7 @@ namespace Kernel
if (only_free && !is_range_free(vaddr, bytes)) if (only_free && !is_range_free(vaddr, bytes))
return false; return false;
for (size_t offset = 0; offset < bytes; offset += PAGE_SIZE) for (size_t offset = 0; offset < bytes; offset += PAGE_SIZE)
reserve_page(vaddr + offset, true, false); reserve_page(vaddr + offset);
Processor::broadcast_smp_message({
.type = Processor::SMPMessage::Type::FlushTLB,
.flush_tlb = {
.vaddr = vaddr,
.page_count = bytes / PAGE_SIZE,
.page_table = vaddr < KERNEL_OFFSET ? this : nullptr,
}
});
return true; return true;
} }
@@ -866,7 +847,7 @@ namespace Kernel
last_address -= rem; last_address -= rem;
ASSERT(is_canonical(first_address)); ASSERT(is_canonical(first_address));
ASSERT(is_canonical(last_address - 1)); ASSERT(is_canonical(last_address));
const vaddr_t uc_vaddr_start = uncanonicalize(first_address); const vaddr_t uc_vaddr_start = uncanonicalize(first_address);
const vaddr_t uc_vaddr_end = uncanonicalize(last_address); const vaddr_t uc_vaddr_end = uncanonicalize(last_address);
@@ -948,7 +929,7 @@ namespace Kernel
last_address -= rem; last_address -= rem;
ASSERT(is_canonical(first_address)); ASSERT(is_canonical(first_address));
ASSERT(is_canonical(last_address - 1)); ASSERT(is_canonical(last_address));
SpinLockGuard _(m_lock); SpinLockGuard _(m_lock);

View File

@@ -2,83 +2,55 @@
// stack contains // stack contains
// return address // return address
// return stack
// return rflags
// siginfo_t
// signal number // signal number
// signal handler // signal handler
.global signal_trampoline .global signal_trampoline
signal_trampoline: signal_trampoline:
pushq %r15 // gregs pushq %rax
pushq %r14
pushq %r13
pushq %r12
pushq %r11
pushq %r10
pushq %r9
pushq %r8
pushq %rsi
pushq %rdi
pushq %rdx
pushq %rcx
pushq %rbx pushq %rbx
pushq %rax pushq %rcx
pushq %rdx
pushq %rbp pushq %rbp
pushq %rdi
pushq %rsi
pushq %r8
pushq %r9
pushq %r10
pushq %r11
pushq %r12
pushq %r13
pushq %r14
pushq %r15
// FIXME: populate these movq 128(%rsp), %rdi
xorq %rax, %rax movq 120(%rsp), %rax
pushq %rax // stack
pushq %rax
pushq %rax
pushq %rax // sigset
pushq %rax // link
movq %rsp, %rdx // ucontext
leaq 176(%rsp), %rsi // siginfo
movq 168(%rsp), %rdi // signal number
movq 160(%rsp), %rax // handler
// align stack to 16 bytes // align stack to 16 bytes
movq %rsp, %rbp movq %rsp, %rbp
andq $-16, %rsp andq $-16, %rsp
subq $512, %rsp
fxsave64 (%rsp)
call *%rax call *%rax
fxrstor64 (%rsp)
addq $512, %rsp
// restore stack // restore stack
movq %rbp, %rsp movq %rbp, %rsp
addq $40, %rsp
// restore registers
popq %rbp
popq %rax
popq %rbx
popq %rcx
popq %rdx
popq %rdi
popq %rsi
popq %r8
popq %r9
popq %r10
popq %r11
popq %r12
popq %r13
popq %r14
popq %r15 popq %r15
popq %r14
popq %r13
popq %r12
popq %r11
popq %r10
popq %r9
popq %r8
popq %rsi
popq %rdi
popq %rbp
popq %rdx
popq %rcx
popq %rbx
popq %rax
// skip handler, number, siginfo_t addq $16, %rsp
addq $72, %rsp
// restore flags // return over red-zone
popfq
movq (%rsp), %rsp
// return over red-zone and siginfo_t
ret $128 ret $128

View File

@@ -1,26 +1,49 @@
// arguments in RAX, RBX, RCX, RDX, RSI, RDI
// System V ABI: RDI, RSI, RDX, RCX, R8, R9
.global asm_syscall_handler .global asm_syscall_handler
asm_syscall_handler: asm_syscall_handler:
swapgs pushq %rbx
movq %rsp, %rax
movq %gs:8, %rsp
pushq $(0x20 | 3)
pushq %rax
pushq %r11
pushq $(0x28 | 3)
pushq %rcx pushq %rcx
subq $8, %rsp pushq %rdx
pushq %rdi
pushq %rsi
pushq %rbp
pushq %r8
pushq %r9
pushq %r10
pushq %r11
pushq %r12
pushq %r13
pushq %r14
pushq %r15
cld
movq %r10, %rcx movq %rsi, %r8
movq %rdi, %r9
movq %rax, %rdi
movq %rbx, %rsi
xchgq %rcx, %rdx
leaq 112(%rsp), %rbx
pushq %rbx
call cpp_syscall_handler call cpp_syscall_handler
addq $8, %rsp
movq 8(%rsp), %rcx popq %r15
movq 24(%rsp), %r11 popq %r14
movq 32(%rsp), %rsp popq %r13
popq %r12
popq %r11
popq %r10
popq %r9
popq %r8
popq %rbp
popq %rsi
popq %rdi
popq %rdx
popq %rcx
popq %rbx
iretq
swapgs
sysretq
.global sys_fork_trampoline .global sys_fork_trampoline
sys_fork_trampoline: sys_fork_trampoline:
@@ -33,7 +56,7 @@ sys_fork_trampoline:
call read_ip call read_ip
testq %rax, %rax testq %rax, %rax
je .done je .reload_stack
movq %rax, %rsi movq %rax, %rsi
movq %rsp, %rdi movq %rsp, %rdi
@@ -47,3 +70,9 @@ sys_fork_trampoline:
popq %rbp popq %rbp
popq %rbx popq %rbx
ret ret
.reload_stack:
call get_thread_start_sp
movq %rax, %rsp
xorq %rax, %rax
jmp .done

View File

@@ -27,9 +27,9 @@ start_kernel_thread:
.global start_userspace_thread .global start_userspace_thread
start_userspace_thread: start_userspace_thread:
call load_thread_sse
call get_thread_start_sp call get_thread_start_sp
movq %rax, %rsp movq %rax, %rsp
swapgs
iretq iretq

View File

@@ -1,87 +0,0 @@
# bool safe_user_memcpy(void*, const void*, size_t)
.global safe_user_memcpy
.global safe_user_memcpy_end
.global safe_user_memcpy_fault
safe_user_memcpy:
xorq %rax, %rax
movq %rdx, %rcx
rep movsb
incq %rax
safe_user_memcpy_fault:
ret
safe_user_memcpy_end:
# bool safe_user_strncpy(void*, const void*, size_t)
.global safe_user_strncpy
.global safe_user_strncpy_end
.global safe_user_strncpy_fault
safe_user_strncpy:
movq %rdx, %rcx
testq %rcx, %rcx
jz safe_user_strncpy_fault
.safe_user_strncpy_align_loop:
testb $0x7, %sil
jz .safe_user_strncpy_align_done
movb (%rsi), %al
movb %al, (%rdi)
testb %al, %al
jz .safe_user_strncpy_done
incq %rdi
incq %rsi
decq %rcx
jnz .safe_user_strncpy_align_loop
jmp safe_user_strncpy_fault
.safe_user_strncpy_align_done:
movq $0x0101010101010101, %r8
movq $0x8080808080808080, %r9
.safe_user_strncpy_qword_loop:
cmpq $8, %rcx
jb .safe_user_strncpy_qword_done
movq (%rsi), %rax
movq %rax, %r10
movq %rax, %r11
# https://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
subq %r8, %r10
notq %r11
andq %r11, %r10
andq %r9, %r10
jnz .safe_user_strncpy_byte_loop
movq %rax, (%rdi)
addq $8, %rdi
addq $8, %rsi
subq $8, %rcx
jnz .safe_user_strncpy_qword_loop
jmp safe_user_strncpy_fault
.safe_user_strncpy_qword_done:
testq %rcx, %rcx
jz safe_user_strncpy_fault
.safe_user_strncpy_byte_loop:
movb (%rsi), %al
movb %al, (%rdi)
testb %al, %al
jz .safe_user_strncpy_done
incq %rdi
incq %rsi
decq %rcx
jnz .safe_user_strncpy_byte_loop
safe_user_strncpy_fault:
xorq %rax, %rax
ret
.safe_user_strncpy_done:
movb $1, %al
ret
safe_user_strncpy_end:

View File

@@ -1,29 +0,0 @@
.global asm_yield_trampoline
asm_yield_trampoline:
leaq 8(%rsp), %rcx
movq %rdi, %rsp
subq $8, %rsp
pushq -8(%rcx)
pushq %rcx
pushq %rax
pushq %rbx
pushq %rbp
pushq %r12
pushq %r13
pushq %r14
pushq %r15
movq %rsp, %rdi
call scheduler_on_yield
popq %r15
popq %r14
popq %r13
popq %r12
popq %rbp
popq %rbx
popq %rax
movq 8(%rsp), %rcx
movq 0(%rsp), %rsp
jmp *%rcx

View File

@@ -14,23 +14,6 @@
# multiboot2 header # multiboot2 header
.section .multiboot, "aw" .section .multiboot, "aw"
.align 8 .align 8
multiboot_start:
.long 0x1BADB002
.long (1 << 2) # page align modules
.long -(0x1BADB002 + (1 << 2))
.long 0
.long 0
.long 0
.long 0
.long 0
.long 0
.long FB_WIDTH
.long FB_HEIGHT
.long FB_BPP
multiboot_end:
.align 8
multiboot2_start: multiboot2_start:
.long 0xE85250D6 .long 0xE85250D6
.long 0 .long 0
@@ -53,12 +36,6 @@ multiboot2_start:
.long 12 .long 12
.long V2P(_start) .long V2P(_start)
# page align modules
.align 8
.short 6
.short 0
.long 8
.align 8 .align 8
.short 0 .short 0
.short 0 .short 0
@@ -76,10 +53,9 @@ bananboot_start:
bananboot_end: bananboot_end:
.section .bss, "aw", @nobits .section .bss, "aw", @nobits
.global g_boot_stack_top boot_stack_bottom:
g_boot_stack_bottom: .skip 4096 * 64
.skip 4096 * 4 boot_stack_top:
g_boot_stack_top:
.global g_kernel_cmdline .global g_kernel_cmdline
g_kernel_cmdline: g_kernel_cmdline:
@@ -179,13 +155,6 @@ enable_sse:
movl %eax, %cr4 movl %eax, %cr4
ret ret
enable_tsc:
# allow userspace to use RDTSC
movl %cr4, %ecx
andl $0xFFFFFFFB, %ecx
movl %ecx, %cr4
ret
initialize_paging: initialize_paging:
# enable PAE # enable PAE
movl %cr4, %ecx movl %cr4, %ecx
@@ -218,11 +187,10 @@ _start:
movl %eax, V2P(bootloader_magic) movl %eax, V2P(bootloader_magic)
movl %ebx, V2P(bootloader_info) movl %ebx, V2P(bootloader_info)
movl $V2P(g_boot_stack_top), %esp movl $V2P(boot_stack_top), %esp
call check_requirements call check_requirements
call enable_sse call enable_sse
call enable_tsc
call initialize_paging call initialize_paging
# flush gdt and jump to 64 bit # flush gdt and jump to 64 bit
@@ -309,7 +277,6 @@ ap_protected_mode:
movb $1, AP_V2P(ap_stack_loaded) movb $1, AP_V2P(ap_stack_loaded)
leal V2P(enable_sse), %ecx; call *%ecx leal V2P(enable_sse), %ecx; call *%ecx
leal V2P(enable_tsc), %ecx; call *%ecx
leal V2P(initialize_paging), %ecx; call *%ecx leal V2P(initialize_paging), %ecx; call *%ecx
# load boot gdt and enter long mode # load boot gdt and enter long mode

View File

@@ -1,12 +1,4 @@
.macro swapgs_if_necessary, n .macro pushaq
testb $3, \n(%rsp)
jz 1f; jnp 1f
swapgs
1:
.endm
.macro pushaq, n
swapgs_if_necessary \n
pushq %rax pushq %rax
pushq %rcx pushq %rcx
pushq %rdx pushq %rdx
@@ -24,7 +16,7 @@
pushq %r15 pushq %r15
.endm .endm
.macro popaq, n .macro popaq
popq %r15 popq %r15
popq %r14 popq %r14
popq %r13 popq %r13
@@ -40,11 +32,10 @@
popq %rdx popq %rdx
popq %rcx popq %rcx
popq %rax popq %rax
swapgs_if_necessary \n
.endm .endm
isr_stub: isr_stub:
pushaq 24 pushaq
cld cld
movq %cr0, %rax; pushq %rax movq %cr0, %rax; pushq %rax
movq %cr2, %rax; pushq %rax movq %cr2, %rax; pushq %rax
@@ -58,33 +49,43 @@ isr_stub:
call cpp_isr_handler call cpp_isr_handler
addq $32, %rsp addq $32, %rsp
popaq 24 popaq
addq $16, %rsp addq $16, %rsp
iretq iretq
irq_stub: irq_stub:
pushaq 24 pushaq
cld cld
movq 120(%rsp), %rdi # irq number movq 120(%rsp), %rdi # irq number
call cpp_irq_handler call cpp_irq_handler
popaq 24 popaq
addq $16, %rsp addq $16, %rsp
iretq iretq
.global asm_yield_handler
asm_yield_handler:
pushaq
cld
leaq 120(%rsp), %rdi # interrupt stack ptr
movq %rsp, %rsi # interrupt register ptr
call cpp_yield_handler
popaq
iretq
.global asm_ipi_handler .global asm_ipi_handler
asm_ipi_handler: asm_ipi_handler:
pushaq 8 pushaq
cld cld
call cpp_ipi_handler call cpp_ipi_handler
popaq 8 popaq
iretq iretq
.global asm_timer_handler .global asm_timer_handler
asm_timer_handler: asm_timer_handler:
pushaq 8 pushaq
cld cld
call cpp_timer_handler call cpp_timer_handler
popaq 8 popaq
iretq iretq
.macro isr n .macro isr n

View File

@@ -2,7 +2,6 @@
#include <BAN/Vector.h> #include <BAN/Vector.h>
#include <kernel/ACPI/AML/Namespace.h> #include <kernel/ACPI/AML/Namespace.h>
#include <kernel/ACPI/EmbeddedController.h>
#include <kernel/ACPI/Headers.h> #include <kernel/ACPI/Headers.h>
#include <kernel/Memory/Types.h> #include <kernel/Memory/Types.h>
#include <kernel/ThreadBlocker.h> #include <kernel/ThreadBlocker.h>
@@ -36,12 +35,8 @@ namespace Kernel::ACPI
BAN::ErrorOr<void> poweroff(); BAN::ErrorOr<void> poweroff();
BAN::ErrorOr<void> reset(); BAN::ErrorOr<void> reset();
BAN::ErrorOr<void> register_gpe_handler(uint8_t gpe, void (*callback)(void*), void* argument);
void handle_irq() override; void handle_irq() override;
BAN::Span<BAN::UniqPtr<EmbeddedController>> embedded_controllers() { return m_embedded_controllers.span(); }
private: private:
ACPI() = default; ACPI() = default;
BAN::ErrorOr<void> initialize_impl(); BAN::ErrorOr<void> initialize_impl();
@@ -55,12 +50,6 @@ namespace Kernel::ACPI
BAN::ErrorOr<void> route_interrupt_link_device(const AML::Scope& device, uint64_t& routed_irq_mask); BAN::ErrorOr<void> route_interrupt_link_device(const AML::Scope& device, uint64_t& routed_irq_mask);
BAN::ErrorOr<void> initialize_embedded_controller(const AML::Scope& embedded_controller);
BAN::ErrorOr<void> initialize_embedded_controllers();
BAN::Optional<GAS> find_gpe_block(size_t index);
bool enable_gpe(uint8_t gpe);
private: private:
paddr_t m_header_table_paddr = 0; paddr_t m_header_table_paddr = 0;
vaddr_t m_header_table_vaddr = 0; vaddr_t m_header_table_vaddr = 0;
@@ -79,23 +68,8 @@ namespace Kernel::ACPI
ThreadBlocker m_event_thread_blocker; ThreadBlocker m_event_thread_blocker;
BAN::Vector<BAN::UniqPtr<EmbeddedController>> m_embedded_controllers;
struct GPEHandler
{
bool has_callback { false };
union {
AML::Reference* method;
struct
{
void (*callback)(void*);
void* argument;
};
};
};
bool m_has_any_gpes { false };
AML::Scope m_gpe_scope; AML::Scope m_gpe_scope;
BAN::Array<GPEHandler, 0xFF> m_gpe_methods; BAN::Array<AML::Reference*, 0xFF> m_gpe_methods { nullptr };
bool m_hardware_reduced { false }; bool m_hardware_reduced { false };
AML::Namespace* m_namespace { nullptr }; AML::Namespace* m_namespace { nullptr };

View File

@@ -50,7 +50,6 @@ namespace Kernel::ACPI::AML
BAN::ErrorOr<void> for_each_child(const Scope&, const BAN::Function<BAN::Iteration(const Scope&, Reference*)>&); BAN::ErrorOr<void> for_each_child(const Scope&, const BAN::Function<BAN::Iteration(const Scope&, Reference*)>&);
BAN::ErrorOr<BAN::Vector<Scope>> find_device_with_eisa_id(BAN::StringView eisa_id); BAN::ErrorOr<BAN::Vector<Scope>> find_device_with_eisa_id(BAN::StringView eisa_id);
BAN::ErrorOr<BAN::Vector<Scope>> find_device_with_eisa_id(BAN::Span<BAN::StringView> eisa_ids);
private: private:
BAN::ErrorOr<Scope> resolve_path(const Scope& scope, const NameString& name_string); BAN::ErrorOr<Scope> resolve_path(const Scope& scope, const NameString& name_string);

View File

@@ -89,9 +89,6 @@ namespace Kernel::ACPI::AML
GAS::AddressSpaceID address_space; GAS::AddressSpaceID address_space;
uint64_t offset; uint64_t offset;
uint64_t length; uint64_t length;
alignas(Scope) uint8_t scope_storage[sizeof(Scope)];
Scope& scope() { return *reinterpret_cast<Scope*>(scope_storage); }
const Scope& scope() const { return *reinterpret_cast<const Scope*>(scope_storage); }
}; };
struct FieldUnit struct FieldUnit

View File

@@ -1,69 +0,0 @@
#pragma once
#include <BAN/Atomic.h>
#include <BAN/UniqPtr.h>
#include <kernel/ACPI/AML/Scope.h>
#include <kernel/Lock/Mutex.h>
#include <kernel/Thread.h>
namespace Kernel::ACPI
{
class EmbeddedController
{
public:
static BAN::ErrorOr<BAN::UniqPtr<EmbeddedController>> create(AML::Scope&& scope, uint16_t command_port, uint16_t data_port, BAN::Optional<uint8_t> gpe);
~EmbeddedController();
BAN::ErrorOr<uint8_t> read_byte(uint8_t offset);
BAN::ErrorOr<void> write_byte(uint8_t offset, uint8_t value);
const AML::Scope& scope() const { return m_scope; }
private:
EmbeddedController(AML::Scope&& scope, uint16_t command_port, uint16_t data_port, bool has_gpe)
: m_scope(BAN::move(scope))
, m_command_port(command_port)
, m_data_port(data_port)
, m_has_gpe(has_gpe)
{ }
private:
void wait_status_bit(uint8_t bit, uint8_t value);
uint8_t read_one(uint16_t port);
void write_one(uint16_t port, uint8_t value);
static void handle_gpe_wrapper(void*);
void handle_gpe();
BAN::ErrorOr<void> call_query_method(uint8_t notification);
void thread_task();
struct Command
{
uint8_t command;
BAN::Optional<uint8_t> data1;
BAN::Optional<uint8_t> data2;
uint8_t* response;
BAN::Atomic<bool> done;
};
BAN::ErrorOr<void> send_command(Command& command);
private:
const AML::Scope m_scope;
const uint16_t m_command_port;
const uint16_t m_data_port;
const bool m_has_gpe;
Mutex m_mutex;
ThreadBlocker m_thread_blocker;
BAN::Optional<Command*> m_queued_command;
Thread* m_thread { nullptr };
};
}

View File

@@ -1,179 +0,0 @@
#pragma once
#include <BAN/ByteSpan.h>
#include <BAN/Debug.h>
#include <BAN/Optional.h>
namespace Kernel::ACPI
{
struct ResourceData
{
enum class Type
{
IRQ,
DMA,
IOPort,
FixedIOPort,
FixedDMA,
// TODO: large stuff the stuff :)
};
union {
struct {
uint16_t irq_mask;
union {
struct {
uint8_t edge_triggered : 1;
uint8_t : 2;
uint8_t active_low : 1;
uint8_t shared : 1;
uint8_t wake_capable : 1;
uint8_t : 2;
};
uint8_t raw;
};
} irq;
struct {
uint8_t channel_mask;
union {
struct {
uint8_t type : 2; // 0: 8 bit, 1: 8 and 16 bit, 2: 16 bit only
uint8_t bus_master : 1;
uint8_t : 2;
uint8_t channel_speed : 2; // 0: compatibility, 1: type A, 2: type B, 3: type F
uint8_t : 1;
};
uint8_t raw;
};
} dma;
struct {
uint16_t range_min_base;
uint16_t range_max_base;
uint8_t base_alignment;
uint8_t range_length;
} io_port;
struct {
uint16_t range_base;
uint8_t range_length;
} fixed_io_port;
struct {
uint16_t request_line;
uint16_t channel;
uint8_t transfer_width; // 0: 8 bit, 1: 16 bit, 2: 32 bit, 3: 64 bit, 4: 128 bit
} fixed_dma;
} as;
Type type;
};
class ResourceParser
{
public:
ResourceParser(BAN::ConstByteSpan buffer)
: m_buffer(buffer)
{}
BAN::Optional<ResourceData> get_next()
{
for (;;)
{
if (m_buffer.empty())
return {};
if (m_buffer[0] & 0x80)
{
dprintln("Skipping large resource 0x{2H}", m_buffer[0] & 0x7F);
const uint16_t length = (m_buffer[2] << 8) | m_buffer[1];
if (m_buffer.size() < static_cast<size_t>(3 + length))
return {};
m_buffer = m_buffer.slice(3 + length);
continue;
}
const uint8_t length = m_buffer[0] & 0x07;
if (m_buffer.size() < static_cast<size_t>(1 + length))
return {};
BAN::Optional<ResourceData> result;
switch ((m_buffer[0] >> 3) & 0x0F)
{
case 0x04:
if (length < 2)
break;
result = ResourceData {
.as = { .irq = {
.irq_mask = static_cast<uint16_t>((m_buffer[2] << 8) | m_buffer[1]),
.raw = (length >= 3) ? m_buffer[3] : static_cast<uint8_t>(1),
}},
.type = ResourceData::Type::IRQ,
};
break;
case 0x05:
if (length < 2)
break;
result = ResourceData {
.as = { .dma = {
.channel_mask = m_buffer[1],
.raw = m_buffer[2],
}},
.type = ResourceData::Type::DMA,
};
break;
case 0x08:
if (length < 7)
break;
result = ResourceData {
.as = { .io_port = {
.range_min_base = static_cast<uint16_t>(((m_buffer[3] << 8) | m_buffer[2]) & ((m_buffer[1] & 1) ? 0xFFFF : 0x03FF)),
.range_max_base = static_cast<uint16_t>(((m_buffer[5] << 8) | m_buffer[4]) & ((m_buffer[1] & 1) ? 0xFFFF : 0x03FF)),
.base_alignment = m_buffer[6],
.range_length = m_buffer[7],
}},
.type = ResourceData::Type::IOPort,
};
break;
case 0x09:
if (length < 3)
break;
result = ResourceData {
.as = { .fixed_io_port = {
.range_base = static_cast<uint16_t>(((m_buffer[2] << 8) | m_buffer[1]) & 0x03FF),
.range_length = m_buffer[3],
}},
.type = ResourceData::Type::FixedIOPort,
};
break;
case 0x0A:
if (length < 5)
break;
result = ResourceData {
.as = { .fixed_dma = {
.request_line = static_cast<uint16_t>((m_buffer[2] << 8) | m_buffer[1]),
.channel = static_cast<uint16_t>((m_buffer[4] << 8) | m_buffer[3]),
.transfer_width = m_buffer[5],
}},
.type = ResourceData::Type::FixedDMA,
};
break;
case 0x0F:
// End tag
return {};
case 0x06:
case 0x07:
case 0x0E:
dprintln("Skipping short resource 0x{2H}", (m_buffer[0] >> 3) & 0x0F);
break;
}
m_buffer = m_buffer.slice(1 + length);
if (result.has_value())
return result.release_value();
}
}
private:
BAN::ConstByteSpan m_buffer;
};
}

View File

@@ -1,37 +0,0 @@
#pragma once
#include <stdint.h>
namespace Kernel::API
{
enum SharedPageFeature : uint32_t
{
SPF_GETTIME = 1 << 0,
};
struct SharedPage
{
uint8_t __sequence[0x100];
uint32_t features;
struct
{
uint8_t shift;
uint64_t mult;
uint64_t realtime_seconds;
} gettime_shared;
struct
{
struct
{
uint32_t seq;
uint64_t last_ns;
uint64_t last_tsc;
} gettime_local;
} cpus[];
};
}

View File

@@ -1,44 +0,0 @@
#pragma once
#include <kernel/Attributes.h>
#include <kernel/IDT.h>
#include <stdint.h>
#include <sys/syscall.h>
namespace Kernel
{
ALWAYS_INLINE long syscall(int syscall, uintptr_t arg1 = 0, uintptr_t arg2 = 0, uintptr_t arg3 = 0, uintptr_t arg4 = 0, uintptr_t arg5 = 0)
{
long ret;
#if ARCH(x86_64)
register uintptr_t r10 asm("r10") = arg3;
register uintptr_t r8 asm( "r8") = arg4;
register uintptr_t r9 asm( "r9") = arg5;
asm volatile(
"syscall"
: "=a"(ret)
, "+D"(syscall)
, "+S"(arg1)
, "+d"(arg2)
, "+r"(r10)
, "+r"(r8)
, "+r"(r9)
:: "rcx", "r11", "memory");
#elif ARCH(i686)
asm volatile(
"int %[irq]"
: "=a"(ret)
: [irq]"i"(static_cast<int>(IRQ_SYSCALL)) // WTF GCC 15
, "a"(syscall)
, "b"(arg1)
, "c"(arg2)
, "d"(arg3)
, "S"(arg4)
, "D"(arg5)
: "memory");
#endif
return ret;
}
}

View File

@@ -1,59 +0,0 @@
#pragma once
#include <kernel/Audio/Controller.h>
#include <kernel/Memory/DMARegion.h>
namespace Kernel
{
class AC97AudioController final : public AudioController, public Interruptable
{
public:
static BAN::ErrorOr<void> create(PCI::Device& pci_device);
void handle_irq() override;
protected:
void handle_new_data() override;
uint32_t get_channels() const override { return 2; }
uint32_t get_sample_rate() const override { return 48000; }
uint32_t get_total_pins() const override { return 1; }
uint32_t get_current_pin() const override { return 0; }
BAN::ErrorOr<void> set_current_pin(uint32_t pin) override { if (pin != 0) return BAN::Error::from_errno(EINVAL); return {}; }
BAN::ErrorOr<void> set_volume_mdB(int32_t) override;
private:
AC97AudioController(PCI::Device& pci_device)
: m_pci_device(pci_device)
{ }
uint32_t get_volume_data() const;
BAN::ErrorOr<void> initialize();
BAN::ErrorOr<void> initialize_bld();
BAN::ErrorOr<void> initialize_interrupts();
bool queue_samples_to_bld();
private:
static constexpr size_t m_bdl_entries = 32;
static constexpr size_t m_samples_per_entry = 0x1000;
// We only store samples in 2 BDL entries at a time to reduce the amount of samples queued.
// This is to reduce latency as you cannot remove data already passed to the BDLs
static constexpr size_t m_used_bdl_entries = 2;
PCI::Device& m_pci_device;
BAN::UniqPtr<PCI::BarRegion> m_mixer;
BAN::UniqPtr<PCI::BarRegion> m_bus_master;
BAN::UniqPtr<DMARegion> m_bdl_region;
uint32_t m_bdl_tail { 0 };
uint32_t m_bdl_head { 0 };
};
}

View File

@@ -1,15 +0,0 @@
#pragma once
#include <stdint.h>
namespace Kernel::AC97
{
struct BufferDescriptorListEntry
{
uint32_t address;
uint16_t samples;
uint16_t flags; // bit 14: last entry, bit 15: IOC
};
}

View File

@@ -1,58 +0,0 @@
#pragma once
#include <kernel/Device/Device.h>
#include <kernel/Memory/ByteRingBuffer.h>
#include <kernel/PCI.h>
#include <sys/ioctl.h>
namespace Kernel
{
class AudioController : public CharacterDevice
{
public:
static BAN::ErrorOr<void> create(PCI::Device& pci_device);
dev_t rdev() const override { return m_rdev; }
BAN::StringView name() const override { return m_name; }
protected:
AudioController();
BAN::ErrorOr<void> initialize();
virtual void handle_new_data() = 0;
virtual uint32_t get_channels() const = 0;
virtual uint32_t get_sample_rate() const = 0;
virtual uint32_t get_total_pins() const = 0;
virtual uint32_t get_current_pin() const = 0;
virtual BAN::ErrorOr<void> set_current_pin(uint32_t) = 0;
virtual BAN::ErrorOr<void> set_volume_mdB(int32_t) = 0;
bool can_read_impl() const override { return false; }
bool can_write_impl() const override { SpinLockGuard _(m_spinlock); return !m_sample_data->full(); }
bool has_error_impl() const override { return false; }
bool has_hungup_impl() const override { return false; }
BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override;
BAN::ErrorOr<long> ioctl_impl(int cmd, void* arg) override;
protected:
ThreadBlocker m_sample_data_blocker;
mutable SpinLock m_spinlock;
static constexpr size_t m_sample_data_capacity = 1 << 20;
BAN::UniqPtr<ByteRingBuffer> m_sample_data;
snd_volume_info m_volume_info {};
private:
const dev_t m_rdev;
char m_name[10] {};
};
}

View File

@@ -1,80 +0,0 @@
#pragma once
#include <kernel/Audio/Controller.h>
#include <kernel/Audio/HDAudio/Controller.h>
namespace Kernel
{
class HDAudioController;
class HDAudioFunctionGroup final : public AudioController
{
public:
static BAN::ErrorOr<BAN::RefPtr<HDAudioFunctionGroup>> create(BAN::RefPtr<HDAudioController>, uint8_t cid, HDAudio::AFGNode&&);
void on_stream_interrupt(uint8_t stream_index);
protected:
// FIXME: allow setting these :D
uint32_t get_channels() const override { return 2; }
uint32_t get_sample_rate() const override { return 48000; }
uint32_t get_total_pins() const override;
uint32_t get_current_pin() const override;
BAN::ErrorOr<void> set_current_pin(uint32_t) override;
BAN::ErrorOr<void> set_volume_mdB(int32_t) override;
void handle_new_data() override;
private:
HDAudioFunctionGroup(BAN::RefPtr<HDAudioController> controller, uint8_t cid, HDAudio::AFGNode&& afg_node)
: m_controller(controller)
, m_afg_node(BAN::move(afg_node))
, m_cid(cid)
{ }
~HDAudioFunctionGroup();
BAN::ErrorOr<void> initialize();
BAN::ErrorOr<void> initialize_stream();
BAN::ErrorOr<void> initialize_output();
BAN::ErrorOr<void> enable_output_path(uint8_t index);
BAN::ErrorOr<void> disable_output_path(uint8_t index);
void reset_stream();
BAN::ErrorOr<void> recurse_output_paths(const HDAudio::AFGWidget& widget, BAN::Vector<const HDAudio::AFGWidget*>& path);
uint16_t get_format_data() const;
size_t bdl_offset() const;
void queue_bdl_data();
private:
// use 6 512 sample BDL entries
// each entry is ~10.7 ms at 48 kHz
// -> total buffered audio is 64 ms
static constexpr size_t m_bdl_entry_sample_frames = 512;
static constexpr size_t m_bdl_entry_count = 6;
BAN::RefPtr<HDAudioController> m_controller;
const HDAudio::AFGNode m_afg_node;
const uint8_t m_cid;
BAN::Vector<BAN::Vector<const HDAudio::AFGWidget*>> m_output_paths;
BAN::Vector<const HDAudio::AFGWidget*> m_output_pins;
size_t m_output_path_index { SIZE_MAX };
uint8_t m_stream_id { 0xFF };
uint8_t m_stream_index { 0xFF };
BAN::UniqPtr<DMARegion> m_bdl_region;
size_t m_bdl_head { 0 };
size_t m_bdl_tail { 0 };
bool m_stream_running { false };
};
}

View File

@@ -1,77 +0,0 @@
#pragma once
#include <kernel/Audio/Controller.h>
#include <kernel/Audio/HDAudio/Definitions.h>
#include <kernel/Memory/DMARegion.h>
namespace Kernel
{
class HDAudioController : public Interruptable, public BAN::RefCounted<HDAudioController>
{
public:
static BAN::ErrorOr<void> create(PCI::Device& pci_device);
BAN::ErrorOr<uint32_t> send_command(HDAudio::CORBEntry);
uint8_t get_stream_index(HDAudio::StreamType type, uint8_t index) const;
BAN::ErrorOr<uint8_t> allocate_stream_id();
void deallocate_stream_id(uint8_t id);
BAN::ErrorOr<uint8_t> allocate_stream(HDAudio::StreamType type, void* afg);
void deallocate_stream(uint8_t index);
PCI::BarRegion& bar0() { return *m_bar0; }
bool is_64bit() const { return m_is64bit; }
void handle_irq() override;
private:
HDAudioController(PCI::Device& pci_device)
: m_pci_device(pci_device)
{ }
BAN::ErrorOr<void> initialize();
BAN::ErrorOr<void> initialize_ring_buffers();
BAN::ErrorOr<void> reset_controller();
BAN::ErrorOr<HDAudio::Codec> initialize_codec(uint8_t codec);
BAN::ErrorOr<HDAudio::AFGNode> initialize_node(uint8_t codec, uint8_t node);
BAN::ErrorOr<HDAudio::AFGWidget> initialize_widget(uint8_t codec, uint8_t node);
private:
struct RingBuffer
{
vaddr_t vaddr;
uint32_t index;
uint32_t size;
};
private:
PCI::Device& m_pci_device;
BAN::UniqPtr<PCI::BarRegion> m_bar0;
bool m_is64bit { false };
bool m_use_immediate_command { false };
uint8_t m_output_streams { 0 };
uint8_t m_input_streams { 0 };
uint8_t m_bidir_streams { 0 };
void* m_allocated_streams[30] {};
// NOTE: stream ids are from 1 to 15
uint16_t m_allocated_stream_ids { 0 };
Mutex m_command_mutex;
SpinLock m_rb_lock;
ThreadBlocker m_rb_blocker;
RingBuffer m_corb;
RingBuffer m_rirb;
BAN::UniqPtr<DMARegion> m_ring_buffer_region;
};
}

View File

@@ -1,90 +0,0 @@
#pragma once
#include <BAN/Vector.h>
namespace Kernel::HDAudio
{
struct CORBEntry
{
union {
struct {
uint32_t data : 8;
uint32_t command : 12;
uint32_t node_index : 8;
uint32_t codec_address : 4;
};
uint32_t raw;
};
};
static_assert(sizeof(CORBEntry) == sizeof(uint32_t));
struct BDLEntry
{
paddr_t address;
uint32_t length;
uint32_t ioc;
};
static_assert(sizeof(BDLEntry) == 16);
struct AFGWidget
{
enum class Type
{
OutputConverter,
InputConverter,
Mixer,
Selector,
PinComplex,
Power,
VolumeKnob,
BeepGenerator,
};
Type type;
uint8_t id;
union
{
struct
{
bool input;
bool output;
bool display; // HDMI or DP
uint32_t config;
} pin_complex;
};
struct Amplifier
{
uint8_t offset;
uint8_t num_steps;
uint8_t step_size;
bool mute;
};
BAN::Optional<Amplifier> output_amplifier;
BAN::Vector<uint16_t> connections;
};
struct AFGNode
{
uint8_t id;
BAN::Vector<AFGWidget> widgets;
};
struct Codec
{
uint8_t id;
BAN::Vector<AFGNode> nodes;
};
enum class StreamType
{
Input,
Output,
Bidirectional,
};
}

View File

@@ -1,50 +0,0 @@
#pragma once
#include <stdint.h>
namespace Kernel::HDAudio
{
enum Regs : uint8_t
{
GCAP = 0x00,
VMIN = 0x02,
VMAJ = 0x03,
GCTL = 0x08,
STATESTS = 0x0E,
INTCTL = 0x20,
INTSTS = 0x24,
CORBLBASE = 0x40,
CORBUBASE = 0x44,
CORBWP = 0x48,
CORBRP = 0x4A,
CORBCTL = 0x4C,
CORBSTS = 0x4D,
CORBSIZE = 0x4E,
RIRBLBASE = 0x50,
RIRBUBASE = 0x54,
RIRBWP = 0x58,
RINTCNT = 0x5A,
RIRBCTL = 0x5C,
RIRBSTS = 0x5D,
RIRBSIZE = 0x5E,
ICOI = 0x60,
ICII = 0x64,
ICIS = 0x68,
SDCTL = 0x00,
SDSTS = 0x03,
SDLPIB = 0x04,
SDCBL = 0x08,
SDLVI = 0x0C,
SDFIFOD = 0x10,
SDFMT = 0x12,
SDBDPL = 0x18,
SDBDPU = 0x1C,
};
}

View File

@@ -41,12 +41,6 @@ namespace Kernel
Type type; Type type;
}; };
struct BootModule
{
paddr_t start;
size_t size;
};
struct BootInfo struct BootInfo
{ {
BAN::String command_line; BAN::String command_line;
@@ -54,7 +48,6 @@ namespace Kernel
RSDP rsdp {}; RSDP rsdp {};
paddr_t kernel_paddr {}; paddr_t kernel_paddr {};
BAN::Vector<BootModule> modules;
BAN::Vector<MemoryMapEntry> memory_map_entries; BAN::Vector<MemoryMapEntry> memory_map_entries;
}; };

View File

@@ -81,6 +81,5 @@ namespace CPUID
bool has_pge(); bool has_pge();
bool has_pat(); bool has_pat();
bool has_1gib_pages(); bool has_1gib_pages();
bool has_invariant_tsc();
} }

View File

@@ -35,8 +35,10 @@ namespace Kernel
bool has_egid(gid_t) const; bool has_egid(gid_t) const;
BAN::Span<const gid_t> groups() const { return m_supplementary.span(); } BAN::ErrorOr<void> initialize_supplementary_groups();
BAN::ErrorOr<void> set_groups(BAN::Span<const gid_t> groups);
private:
BAN::ErrorOr<BAN::String> find_username() const;
private: private:
uid_t m_ruid, m_euid, m_suid; uid_t m_ruid, m_euid, m_suid;

View File

@@ -70,15 +70,10 @@
#define DEBUG_USB_MOUSE 0 #define DEBUG_USB_MOUSE 0
#define DEBUG_USB_MASS_STORAGE 0 #define DEBUG_USB_MASS_STORAGE 0
#define DEBUG_HDAUDIO 0
namespace Debug namespace Debug
{ {
void dump_stack_trace(); void dump_stack_trace();
void dump_stack_trace(uintptr_t ip, uintptr_t bp);
void dump_qr_code();
void putchar(char); void putchar(char);
void print_prefix(const char*, int); void print_prefix(const char*, int);

View File

@@ -3,7 +3,7 @@
namespace Kernel namespace Kernel
{ {
class DebugDevice final : public CharacterDevice class DebugDevice : public CharacterDevice
{ {
public: public:
static BAN::ErrorOr<BAN::RefPtr<DebugDevice>> create(mode_t, uid_t, gid_t); static BAN::ErrorOr<BAN::RefPtr<DebugDevice>> create(mode_t, uid_t, gid_t);
@@ -24,7 +24,6 @@ namespace Kernel
virtual bool can_read_impl() const override { return false; } virtual bool can_read_impl() const override { return false; }
virtual bool can_write_impl() const override { return true; } virtual bool can_write_impl() const override { return true; }
virtual bool has_error_impl() const override { return false; } virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private: private:
const dev_t m_rdev; const dev_t m_rdev;

View File

@@ -16,11 +16,7 @@ namespace Kernel
virtual bool is_partition() const { return false; } virtual bool is_partition() const { return false; }
virtual bool is_storage_device() const { return false; } virtual bool is_storage_device() const { return false; }
virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> mmap_region(PageTable&, off_t offset, size_t len, AddressRange, MemoryRegion::Type, PageTable::flags_t, int status_flags) virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> mmap_region(PageTable&, off_t offset, size_t len, AddressRange, MemoryRegion::Type, PageTable::flags_t) { (void)offset; (void)len; return BAN::Error::from_errno(EINVAL); }
{
(void)offset; (void)len; (void)status_flags;
return BAN::Error::from_errno(ENOTSUP);
}
virtual dev_t rdev() const override = 0; virtual dev_t rdev() const override = 0;

View File

@@ -16,14 +16,11 @@ namespace Kernel
Debug, Debug,
Keyboard, Keyboard,
Mouse, Mouse,
Joystick,
SCSI, SCSI,
NVMeController, NVMeController,
NVMeNamespace, NVMeNamespace,
Ethernet, Ethernet,
Loopback,
TmpFS, TmpFS,
AudioController,
}; };
} }

View File

@@ -10,7 +10,6 @@ namespace Kernel
{ {
public: public:
static BAN::ErrorOr<BAN::RefPtr<FramebufferDevice>> create_from_boot_framebuffer(); static BAN::ErrorOr<BAN::RefPtr<FramebufferDevice>> create_from_boot_framebuffer();
static BAN::RefPtr<FramebufferDevice> boot_framebuffer();
~FramebufferDevice(); ~FramebufferDevice();
uint32_t width() const { return m_width; } uint32_t width() const { return m_width; }
@@ -18,7 +17,6 @@ namespace Kernel
uint32_t get_pixel(uint32_t x, uint32_t y) const; uint32_t get_pixel(uint32_t x, uint32_t y) const;
void set_pixel(uint32_t x, uint32_t y, uint32_t rgb); void set_pixel(uint32_t x, uint32_t y, uint32_t rgb);
void fill(uint32_t rgb);
// positive rows -> empty pixels on bottom // positive rows -> empty pixels on bottom
// negative rows -> empty pixels on top // negative rows -> empty pixels on top
@@ -28,7 +26,7 @@ namespace Kernel
void sync_pixels_linear(uint32_t first_pixel, uint32_t pixel_count); void sync_pixels_linear(uint32_t first_pixel, uint32_t pixel_count);
void sync_pixels_rectangle(uint32_t top_right_x, uint32_t top_right_y, uint32_t width, uint32_t height); void sync_pixels_rectangle(uint32_t top_right_x, uint32_t top_right_y, uint32_t width, uint32_t height);
virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> mmap_region(PageTable&, off_t offset, size_t len, AddressRange, MemoryRegion::Type, PageTable::flags_t, int status_flags) override; virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> mmap_region(PageTable&, off_t offset, size_t len, AddressRange, MemoryRegion::Type, PageTable::flags_t) override;
virtual dev_t rdev() const override { return m_rdev; } virtual dev_t rdev() const override { return m_rdev; }
virtual BAN::StringView name() const override { return m_name.sv(); } virtual BAN::StringView name() const override { return m_name.sv(); }
@@ -40,7 +38,6 @@ namespace Kernel
virtual bool can_read_impl() const override { return true; } virtual bool can_read_impl() const override { return true; }
virtual bool can_write_impl() const override { return true; } virtual bool can_write_impl() const override { return true; }
virtual bool has_error_impl() const override { return false; } virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private: private:
FramebufferDevice(mode_t mode, uid_t uid, gid_t gid, dev_t rdev, paddr_t paddr, uint32_t width, uint32_t height, uint32_t pitch, uint8_t bpp); FramebufferDevice(mode_t mode, uid_t uid, gid_t gid, dev_t rdev, paddr_t paddr, uint32_t width, uint32_t height, uint32_t pitch, uint8_t bpp);

View File

@@ -5,7 +5,7 @@
namespace Kernel namespace Kernel
{ {
class NullDevice final : public CharacterDevice class NullDevice : public CharacterDevice
{ {
public: public:
static BAN::ErrorOr<BAN::RefPtr<NullDevice>> create(mode_t, uid_t, gid_t); static BAN::ErrorOr<BAN::RefPtr<NullDevice>> create(mode_t, uid_t, gid_t);
@@ -26,7 +26,6 @@ namespace Kernel
virtual bool can_read_impl() const override { return false; } virtual bool can_read_impl() const override { return false; }
virtual bool can_write_impl() const override { return true; } virtual bool can_write_impl() const override { return true; }
virtual bool has_error_impl() const override { return false; } virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private: private:
const dev_t m_rdev; const dev_t m_rdev;

View File

@@ -3,7 +3,7 @@
namespace Kernel namespace Kernel
{ {
class RandomDevice final : public CharacterDevice class RandomDevice : public CharacterDevice
{ {
public: public:
static BAN::ErrorOr<BAN::RefPtr<RandomDevice>> create(mode_t, uid_t, gid_t); static BAN::ErrorOr<BAN::RefPtr<RandomDevice>> create(mode_t, uid_t, gid_t);
@@ -24,7 +24,6 @@ namespace Kernel
virtual bool can_read_impl() const override { return true; } virtual bool can_read_impl() const override { return true; }
virtual bool can_write_impl() const override { return false; } virtual bool can_write_impl() const override { return false; }
virtual bool has_error_impl() const override { return false; } virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private: private:
const dev_t m_rdev; const dev_t m_rdev;

View File

@@ -3,7 +3,7 @@
namespace Kernel namespace Kernel
{ {
class ZeroDevice final : public CharacterDevice class ZeroDevice : public CharacterDevice
{ {
public: public:
static BAN::ErrorOr<BAN::RefPtr<ZeroDevice>> create(mode_t, uid_t, gid_t); static BAN::ErrorOr<BAN::RefPtr<ZeroDevice>> create(mode_t, uid_t, gid_t);
@@ -24,7 +24,6 @@ namespace Kernel
virtual bool can_read_impl() const override { return true; } virtual bool can_read_impl() const override { return true; }
virtual bool can_write_impl() const override { return false; } virtual bool can_write_impl() const override { return false; }
virtual bool has_error_impl() const override { return false; } virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private: private:
const dev_t m_rdev; const dev_t m_rdev;

View File

@@ -20,6 +20,6 @@ namespace Kernel::ELF
BAN::Vector<BAN::UniqPtr<MemoryRegion>> regions; BAN::Vector<BAN::UniqPtr<MemoryRegion>> regions;
}; };
BAN::ErrorOr<LoadResult> load_from_inode(BAN::RefPtr<Inode> root, BAN::RefPtr<Inode> inode, const Credentials&, PageTable&); BAN::ErrorOr<LoadResult> load_from_inode(BAN::RefPtr<Inode>, const Credentials&, PageTable&);
} }

View File

@@ -1,109 +0,0 @@
#pragma once
#include <BAN/Array.h>
#include <BAN/CircularQueue.h>
#include <BAN/HashMap.h>
#include <BAN/HashSet.h>
#include <kernel/FS/Inode.h>
#include <limits.h>
#include <sys/epoll.h>
namespace Kernel
{
class Epoll final : public Inode
{
public:
static BAN::ErrorOr<BAN::RefPtr<Epoll>> create();
~Epoll();
BAN::ErrorOr<void> ctl(int op, int fd, BAN::RefPtr<Inode> inode, epoll_event event);
BAN::ErrorOr<size_t> wait(BAN::Span<epoll_event> events, uint64_t waketime_ns);
void notify(BAN::RefPtr<Inode> inode, uint32_t event);
private:
Epoll() = default;
public:
ino_t ino() const override { return 0; }
Mode mode() const override { return { Mode::IRUSR | Mode::IWUSR }; }
nlink_t nlink() const override { return 0; }
uid_t uid() const override { return 0; }
gid_t gid() const override { return 0; }
off_t size() const override { return 0; }
timespec atime() const override { return {}; }
timespec mtime() const override { return {}; }
timespec ctime() const override { return {}; }
blksize_t blksize() const override { return PAGE_SIZE; }
blkcnt_t blocks() const override { return 0; }
dev_t dev() const override { return 0; }
dev_t rdev() const override { return 0; }
bool is_epoll() const override { return true; }
const FileSystem* filesystem() const override { return nullptr; }
bool can_read_impl() const override { return false; }
bool can_write_impl() const override { return false; }
bool has_error_impl() const override { return false; }
bool has_hungup_impl() const override { return false; }
BAN::ErrorOr<void> fsync_impl() override { return {}; }
private:
struct InodeRefPtrHash
{
BAN::hash_t operator()(const BAN::RefPtr<Inode>& inode)
{
return BAN::hash<const Inode*>()(inode.ptr());
}
};
struct ListenEventList
{
BAN::Array<epoll_event, OPEN_MAX> events;
uint32_t bitmap[(OPEN_MAX + 31) / 32] {};
bool has_fd(int fd) const
{
// For some reason having (fd < 0 || ...) makes GCC 15.1.0
// think bitmap access can be out of bounds...
if (static_cast<size_t>(fd) >= events.size())
return false;
return bitmap[fd / 32] & (1u << (fd % 32));
}
bool empty() const
{
for (auto val : bitmap)
if (val != 0)
return false;
return true;
}
void add_fd(int fd, epoll_event event)
{
ASSERT(!has_fd(fd));
bitmap[fd / 32] |= (1u << (fd % 32));
events[fd] = event;
}
void remove_fd(int fd)
{
ASSERT(has_fd(fd));
bitmap[fd / 32] &= ~(1u << (fd % 32));
events[fd] = {};
}
};
private:
ThreadBlocker m_thread_blocker;
SpinLock m_ready_lock;
BAN::HashMap<BAN::RefPtr<Inode>, uint32_t, InodeRefPtrHash> m_ready_events;
BAN::HashMap<BAN::RefPtr<Inode>, uint32_t, InodeRefPtrHash> m_processing_events;
BAN::HashMap<BAN::RefPtr<Inode>, ListenEventList, InodeRefPtrHash> m_listening_events;
};
}

View File

@@ -22,7 +22,6 @@ namespace Kernel
void add_inode(BAN::StringView path, BAN::RefPtr<TmpInode>); void add_inode(BAN::StringView path, BAN::RefPtr<TmpInode>);
void initiate_disk_cache_drop();
void initiate_sync(bool should_block); void initiate_sync(bool should_block);
private: private:
@@ -38,10 +37,6 @@ namespace Kernel
ThreadBlocker m_sync_done; ThreadBlocker m_sync_done;
ThreadBlocker m_sync_thread_blocker; ThreadBlocker m_sync_thread_blocker;
volatile bool m_should_sync { false }; volatile bool m_should_sync { false };
SpinLock m_disk_cache_lock;
ThreadBlocker m_disk_cache_thread_blocker;
BAN::Atomic<bool> m_should_drop_disk_cache { false };
}; };
} }

View File

@@ -1,52 +0,0 @@
#pragma once
#include <kernel/FS/Inode.h>
namespace Kernel
{
class EventFD final : public Inode
{
public:
static BAN::ErrorOr<BAN::RefPtr<Inode>> create(uint64_t initval, bool semaphore);
ino_t ino() const override { return 0; }
Mode mode() const override { return { Mode::IFCHR | Mode::IRUSR | Mode::IWUSR }; }
nlink_t nlink() const override { return ref_count(); }
uid_t uid() const override { return 0; }
gid_t gid() const override { return 0; }
off_t size() const override { return 0; }
timespec atime() const override { return {}; }
timespec mtime() const override { return {}; }
timespec ctime() const override { return {}; }
blksize_t blksize() const override { return 8; }
blkcnt_t blocks() const override { return 0; }
dev_t dev() const override { return 0; }
dev_t rdev() const override { return 0; }
const FileSystem* filesystem() const override { return nullptr; }
protected:
BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override;
BAN::ErrorOr<void> fsync_impl() final override { return {}; }
bool can_read_impl() const override { return m_value > 0; }
bool can_write_impl() const override { return m_value < UINT64_MAX - 1; }
bool has_error_impl() const override { return false; }
bool has_hungup_impl() const override { return false; }
private:
EventFD(uint64_t initval, bool is_semaphore)
: m_is_semaphore(is_semaphore)
, m_value(initval)
{ }
private:
const bool m_is_semaphore;
uint64_t m_value;
ThreadBlocker m_thread_blocker;
};
}

View File

@@ -26,32 +26,18 @@ namespace Kernel
class BlockBufferWrapper class BlockBufferWrapper
{ {
BAN_NON_COPYABLE(BlockBufferWrapper); BAN_NON_COPYABLE(BlockBufferWrapper);
BAN_NON_MOVABLE(BlockBufferWrapper);
public: public:
BlockBufferWrapper(BAN::Span<uint8_t> buffer, void (*callback)(void*, const uint8_t*), void* argument) BlockBufferWrapper(BAN::Span<uint8_t> buffer, bool& used)
: m_buffer(buffer) : m_buffer(buffer)
, m_callback(callback) , m_used(used)
, m_argument(argument) {
{ } ASSERT(m_used);
BlockBufferWrapper(BlockBufferWrapper&& other) { *this = BAN::move(other); } }
~BlockBufferWrapper() ~BlockBufferWrapper()
{ {
if (m_callback == nullptr) m_used = false;
return;
m_callback(m_argument, m_buffer.data());
}
BlockBufferWrapper& operator=(BlockBufferWrapper&& other)
{
this->m_buffer = other.m_buffer;
this->m_callback = other.m_callback;
this->m_argument = other.m_argument;
other.m_buffer = {};
other.m_callback = nullptr;
other.m_argument = nullptr;
return *this;
} }
size_t size() const { return m_buffer.size(); } size_t size() const { return m_buffer.size(); }
@@ -67,8 +53,7 @@ namespace Kernel
private: private:
BAN::Span<uint8_t> m_buffer; BAN::Span<uint8_t> m_buffer;
void (*m_callback)(void*, const uint8_t*); bool& m_used;
void* m_argument;
}; };
public: public:
@@ -77,6 +62,8 @@ namespace Kernel
virtual BAN::RefPtr<Inode> root_inode() override { return m_root_inode; } virtual BAN::RefPtr<Inode> root_inode() override { return m_root_inode; }
virtual dev_t dev() const override { return m_block_device->rdev(); };
private: private:
Ext2FS(BAN::RefPtr<BlockDevice> block_device) Ext2FS(BAN::RefPtr<BlockDevice> block_device)
: m_block_device(block_device) : m_block_device(block_device)
@@ -94,7 +81,7 @@ namespace Kernel
BAN::ErrorOr<void> sync_superblock(); BAN::ErrorOr<void> sync_superblock();
BAN::ErrorOr<void> sync_block(uint32_t block); BAN::ErrorOr<void> sync_block(uint32_t block);
BAN::ErrorOr<BlockBufferWrapper> get_block_buffer(); BlockBufferWrapper get_block_buffer();
BAN::ErrorOr<uint32_t> reserve_free_block(uint32_t primary_bgd); BAN::ErrorOr<uint32_t> reserve_free_block(uint32_t primary_bgd);
BAN::ErrorOr<void> release_block(uint32_t block); BAN::ErrorOr<void> release_block(uint32_t block);
@@ -117,13 +104,10 @@ namespace Kernel
{ {
public: public:
BlockBufferManager() = default; BlockBufferManager() = default;
BAN::ErrorOr<BlockBufferWrapper> get_buffer(); BlockBufferWrapper get_buffer();
BAN::ErrorOr<void> initialize(size_t block_size); BAN::ErrorOr<void> initialize(size_t block_size);
private:
void destroy_callback(const uint8_t* buffer_ptr);
private: private:
struct BlockBuffer struct BlockBuffer
{ {
@@ -131,20 +115,8 @@ namespace Kernel
bool used { false }; bool used { false };
}; };
struct ThreadInfo
{
pid_t tid { 0 };
size_t buffers { 0 };
};
private: private:
static constexpr size_t max_threads = 8; BAN::Array<BlockBuffer, 10> m_buffers;
static constexpr size_t max_buffers_per_thread = 6;
Mutex m_buffer_mutex;
ThreadBlocker m_buffer_blocker;
BAN::Array<BlockBuffer, max_threads * max_buffers_per_thread> m_buffers;
BAN::Array<ThreadInfo, max_threads> m_thread_infos;
}; };
private: private:

View File

@@ -37,7 +37,6 @@ namespace Kernel
virtual BAN::ErrorOr<void> create_file_impl(BAN::StringView, mode_t, uid_t, gid_t) override; virtual BAN::ErrorOr<void> create_file_impl(BAN::StringView, mode_t, uid_t, gid_t) override;
virtual BAN::ErrorOr<void> create_directory_impl(BAN::StringView, mode_t, uid_t, gid_t) override; virtual BAN::ErrorOr<void> create_directory_impl(BAN::StringView, mode_t, uid_t, gid_t) override;
virtual BAN::ErrorOr<void> link_inode_impl(BAN::StringView, BAN::RefPtr<Inode>) override; virtual BAN::ErrorOr<void> link_inode_impl(BAN::StringView, BAN::RefPtr<Inode>) override;
virtual BAN::ErrorOr<void> rename_inode_impl(BAN::RefPtr<Inode>, BAN::StringView, BAN::StringView) override;
virtual BAN::ErrorOr<void> unlink_impl(BAN::StringView) override; virtual BAN::ErrorOr<void> unlink_impl(BAN::StringView) override;
virtual BAN::ErrorOr<BAN::String> link_target_impl() override; virtual BAN::ErrorOr<BAN::String> link_target_impl() override;
@@ -47,32 +46,29 @@ namespace Kernel
virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override; virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override;
virtual BAN::ErrorOr<void> truncate_impl(size_t) override; virtual BAN::ErrorOr<void> truncate_impl(size_t) override;
virtual BAN::ErrorOr<void> chmod_impl(mode_t) override; virtual BAN::ErrorOr<void> chmod_impl(mode_t) override;
virtual BAN::ErrorOr<void> chown_impl(uid_t, gid_t) override;
virtual BAN::ErrorOr<void> utimens_impl(const timespec[2]) override;
virtual BAN::ErrorOr<void> fsync_impl() override; virtual BAN::ErrorOr<void> fsync_impl() override;
virtual bool can_read_impl() const override { return true; } virtual bool can_read_impl() const override { return true; }
virtual bool can_write_impl() const override { return true; } virtual bool can_write_impl() const override { return true; }
virtual bool has_error_impl() const override { return false; } virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private: private:
// Returns maximum number of data blocks in use // Returns maximum number of data blocks in use
// NOTE: the inode might have more blocks than what this suggests if it has been shrinked // NOTE: the inode might have more blocks than what this suggests if it has been shrinked
uint32_t max_used_data_block_count() const { return size() / blksize(); } uint32_t max_used_data_block_count() const { return size() / blksize(); }
BAN::ErrorOr<BAN::Optional<uint32_t>> block_from_indirect_block(uint32_t& block, uint32_t index, uint32_t depth, bool allocate); BAN::ErrorOr<BAN::Optional<uint32_t>> block_from_indirect_block(uint32_t block, uint32_t index, uint32_t depth);
BAN::ErrorOr<BAN::Optional<uint32_t>> fs_block_of_data_block_index(uint32_t data_block_index, bool allocate); BAN::ErrorOr<BAN::Optional<uint32_t>> fs_block_of_data_block_index(uint32_t data_block_index);
BAN::ErrorOr<void> link_inode_to_directory(Ext2Inode&, BAN::StringView name); BAN::ErrorOr<void> link_inode_to_directory(Ext2Inode&, BAN::StringView name);
BAN::ErrorOr<void> remove_inode_from_directory(BAN::StringView name, bool cleanup_directory);
BAN::ErrorOr<bool> is_directory_empty(); BAN::ErrorOr<bool> is_directory_empty();
BAN::ErrorOr<void> cleanup_indirect_block(uint32_t block, uint32_t depth); BAN::ErrorOr<void> cleanup_indirect_block(uint32_t block, uint32_t depth);
BAN::ErrorOr<void> cleanup_default_links(); BAN::ErrorOr<void> cleanup_default_links();
BAN::ErrorOr<void> cleanup_data_blocks();
BAN::ErrorOr<void> cleanup_from_fs(); BAN::ErrorOr<void> cleanup_from_fs();
BAN::ErrorOr<uint32_t> allocate_new_block_to_indirect_block(uint32_t& block, uint32_t index, uint32_t depth);
BAN::ErrorOr<uint32_t> allocate_new_block(uint32_t data_block_index);
BAN::ErrorOr<void> sync(); BAN::ErrorOr<void> sync();
uint32_t block_group() const; uint32_t block_group() const;
@@ -85,26 +81,6 @@ namespace Kernel
{} {}
static BAN::ErrorOr<BAN::RefPtr<Ext2Inode>> create(Ext2FS&, uint32_t); static BAN::ErrorOr<BAN::RefPtr<Ext2Inode>> create(Ext2FS&, uint32_t);
private:
struct ScopedSync
{
ScopedSync(Ext2Inode& inode)
: inode(inode)
, inode_info(inode.m_inode)
{ }
~ScopedSync()
{
if (memcmp(&inode.m_inode, &inode_info, sizeof(Ext2::Inode)) == 0)
return;
if (auto ret = inode.sync(); ret.is_error())
dwarnln("failed to sync inode: {}", ret.error());
}
Ext2Inode& inode;
Ext2::Inode inode_info;
};
private: private:
Ext2FS& m_fs; Ext2FS& m_fs;
Ext2::Inode m_inode; Ext2::Inode m_inode;

View File

@@ -37,6 +37,8 @@ namespace Kernel
virtual BAN::RefPtr<Inode> root_inode() override { return m_root_inode; } virtual BAN::RefPtr<Inode> root_inode() override { return m_root_inode; }
virtual dev_t dev() const override { return m_block_device->rdev(); };
BAN::ErrorOr<BAN::RefPtr<FATInode>> open_inode(BAN::RefPtr<FATInode> parent, const FAT::DirectoryEntry& entry, uint32_t cluster_index, uint32_t entry_index); BAN::ErrorOr<BAN::RefPtr<FATInode>> open_inode(BAN::RefPtr<FATInode> parent, const FAT::DirectoryEntry& entry, uint32_t cluster_index, uint32_t entry_index);
BAN::ErrorOr<void> inode_read_cluster(BAN::RefPtr<FATInode>, size_t index, BAN::ByteSpan buffer); BAN::ErrorOr<void> inode_read_cluster(BAN::RefPtr<FATInode>, size_t index, BAN::ByteSpan buffer);
blksize_t inode_block_size(BAN::RefPtr<const FATInode>) const; blksize_t inode_block_size(BAN::RefPtr<const FATInode>) const;

View File

@@ -44,13 +44,11 @@ namespace Kernel
//virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override; //virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override;
//virtual BAN::ErrorOr<void> truncate_impl(size_t) override; //virtual BAN::ErrorOr<void> truncate_impl(size_t) override;
//virtual BAN::ErrorOr<void> chmod_impl(mode_t) override; //virtual BAN::ErrorOr<void> chmod_impl(mode_t) override;
//virtual BAN::ErrorOr<void> utimens_impl(const timespec[2]) override;
virtual BAN::ErrorOr<void> fsync_impl() override { return {}; } virtual BAN::ErrorOr<void> fsync_impl() override { return {}; }
virtual bool can_read_impl() const override { return true; } virtual bool can_read_impl() const override { return true; }
virtual bool can_write_impl() const override { return true; } virtual bool can_write_impl() const override { return true; }
virtual bool has_error_impl() const override { return false; } virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private: private:
FATInode(FATFS& fs, const FAT::DirectoryEntry& entry, ino_t ino, uint32_t block_count) FATInode(FATFS& fs, const FAT::DirectoryEntry& entry, ino_t ino, uint32_t block_count)

View File

@@ -26,6 +26,8 @@ namespace Kernel
static BAN::ErrorOr<BAN::RefPtr<FileSystem>> from_block_device(BAN::RefPtr<BlockDevice>); static BAN::ErrorOr<BAN::RefPtr<FileSystem>> from_block_device(BAN::RefPtr<BlockDevice>);
virtual BAN::RefPtr<Inode> root_inode() = 0; virtual BAN::RefPtr<Inode> root_inode() = 0;
virtual dev_t dev() const = 0;
}; };
} }

View File

@@ -1,7 +1,6 @@
#pragma once #pragma once
#include <BAN/ByteSpan.h> #include <BAN/ByteSpan.h>
#include <BAN/LinkedList.h>
#include <BAN/RefPtr.h> #include <BAN/RefPtr.h>
#include <BAN/String.h> #include <BAN/String.h>
#include <BAN/StringView.h> #include <BAN/StringView.h>
@@ -20,9 +19,10 @@
namespace Kernel namespace Kernel
{ {
class FileBackedRegion;
class FileSystem; class FileSystem;
struct SharedFileData;
class FileBackedRegion;
class SharedFileData;
class Inode : public BAN::RefCounted<Inode> class Inode : public BAN::RefCounted<Inode>
{ {
@@ -85,7 +85,6 @@ namespace Kernel
virtual dev_t rdev() const = 0; virtual dev_t rdev() const = 0;
virtual bool is_device() const { return false; } virtual bool is_device() const { return false; }
virtual bool is_epoll() const { return false; }
virtual bool is_pipe() const { return false; } virtual bool is_pipe() const { return false; }
virtual bool is_tty() const { return false; } virtual bool is_tty() const { return false; }
@@ -97,7 +96,6 @@ namespace Kernel
BAN::ErrorOr<void> create_file(BAN::StringView, mode_t, uid_t, gid_t); BAN::ErrorOr<void> create_file(BAN::StringView, mode_t, uid_t, gid_t);
BAN::ErrorOr<void> create_directory(BAN::StringView, mode_t, uid_t, gid_t); BAN::ErrorOr<void> create_directory(BAN::StringView, mode_t, uid_t, gid_t);
BAN::ErrorOr<void> link_inode(BAN::StringView, BAN::RefPtr<Inode>); BAN::ErrorOr<void> link_inode(BAN::StringView, BAN::RefPtr<Inode>);
BAN::ErrorOr<void> rename_inode(BAN::RefPtr<Inode>, BAN::StringView, BAN::StringView);
BAN::ErrorOr<void> unlink(BAN::StringView); BAN::ErrorOr<void> unlink(BAN::StringView);
// Link API // Link API
@@ -109,12 +107,9 @@ namespace Kernel
BAN::ErrorOr<void> bind(const sockaddr* address, socklen_t address_len); BAN::ErrorOr<void> bind(const sockaddr* address, socklen_t address_len);
BAN::ErrorOr<void> connect(const sockaddr* address, socklen_t address_len); BAN::ErrorOr<void> connect(const sockaddr* address, socklen_t address_len);
BAN::ErrorOr<void> listen(int backlog); BAN::ErrorOr<void> listen(int backlog);
BAN::ErrorOr<size_t> sendmsg(const msghdr& message, int flags); BAN::ErrorOr<size_t> sendto(BAN::ConstByteSpan message, const sockaddr* address, socklen_t address_len);
BAN::ErrorOr<size_t> recvmsg(msghdr& message, int flags); BAN::ErrorOr<size_t> recvfrom(BAN::ByteSpan buffer, sockaddr* address, socklen_t* address_len);
BAN::ErrorOr<void> getsockname(sockaddr* address, socklen_t* address_len); BAN::ErrorOr<void> getsockname(sockaddr* address, socklen_t* address_len);
BAN::ErrorOr<void> getpeername(sockaddr* address, socklen_t* address_len);
BAN::ErrorOr<void> getsockopt(int level, int option, void* value, socklen_t* value_len);
BAN::ErrorOr<void> setsockopt(int level, int option, const void* value, socklen_t value_len);
// General API // General API
BAN::ErrorOr<size_t> read(off_t, BAN::ByteSpan buffer); BAN::ErrorOr<size_t> read(off_t, BAN::ByteSpan buffer);
@@ -122,33 +117,23 @@ namespace Kernel
BAN::ErrorOr<void> truncate(size_t); BAN::ErrorOr<void> truncate(size_t);
BAN::ErrorOr<void> chmod(mode_t); BAN::ErrorOr<void> chmod(mode_t);
BAN::ErrorOr<void> chown(uid_t, gid_t); BAN::ErrorOr<void> chown(uid_t, gid_t);
BAN::ErrorOr<void> utimens(const timespec[2]);
BAN::ErrorOr<void> fsync(); BAN::ErrorOr<void> fsync();
// Select/Non blocking API // Select/Non blocking API
bool can_read() const; bool can_read() const;
bool can_write() const; bool can_write() const;
bool has_error() const; bool has_error() const;
bool has_hungup() const;
BAN::ErrorOr<long> ioctl(int request, void* arg); BAN::ErrorOr<long> ioctl(int request, void* arg);
BAN::ErrorOr<void> add_epoll(class Epoll*);
void del_epoll(class Epoll*);
void epoll_notify(uint32_t event);
virtual void on_close(int status_flags) { (void)status_flags; }
virtual void on_clone(int status_flags) { (void)status_flags; }
protected: protected:
// Directory API // Directory API
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> find_inode_impl(BAN::StringView) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<BAN::RefPtr<Inode>> find_inode_impl(BAN::StringView) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<size_t> list_next_inodes_impl(off_t, struct dirent*, size_t) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<size_t> list_next_inodes_impl(off_t, struct dirent*, size_t) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> create_file_impl(BAN::StringView, mode_t, uid_t, gid_t) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<void> create_file_impl(BAN::StringView, mode_t, uid_t, gid_t) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> create_directory_impl(BAN::StringView, mode_t, uid_t, gid_t) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<void> create_directory_impl(BAN::StringView, mode_t, uid_t, gid_t) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> link_inode_impl(BAN::StringView, BAN::RefPtr<Inode>) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<void> link_inode_impl(BAN::StringView, BAN::RefPtr<Inode>) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> rename_inode_impl(BAN::RefPtr<Inode>, BAN::StringView, BAN::StringView) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<void> unlink_impl(BAN::StringView) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> unlink_impl(BAN::StringView) { return BAN::Error::from_errno(ENOTSUP); }
// Link API // Link API
virtual BAN::ErrorOr<BAN::String> link_target_impl() { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<BAN::String> link_target_impl() { return BAN::Error::from_errno(ENOTSUP); }
@@ -159,12 +144,9 @@ namespace Kernel
virtual BAN::ErrorOr<void> connect_impl(const sockaddr*, socklen_t) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<void> connect_impl(const sockaddr*, socklen_t) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> listen_impl(int) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<void> listen_impl(int) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> bind_impl(const sockaddr*, socklen_t) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<void> bind_impl(const sockaddr*, socklen_t) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<size_t> recvmsg_impl(msghdr&, int) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<size_t> sendto_impl(BAN::ConstByteSpan, const sockaddr*, socklen_t) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr&, int) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<size_t> recvfrom_impl(BAN::ByteSpan, sockaddr*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> getsockname_impl(sockaddr*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<void> getsockname_impl(sockaddr*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> getsockopt_impl(int, int, void*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> setsockopt_impl(int, int, const void*, socklen_t) { return BAN::Error::from_errno(ENOTSUP); }
// General API // General API
virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) { return BAN::Error::from_errno(ENOTSUP); }
@@ -172,14 +154,12 @@ namespace Kernel
virtual BAN::ErrorOr<void> truncate_impl(size_t) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<void> truncate_impl(size_t) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> chmod_impl(mode_t) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<void> chmod_impl(mode_t) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> chown_impl(uid_t, gid_t) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<void> chown_impl(uid_t, gid_t) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> utimens_impl(const timespec[2]) { return BAN::Error::from_errno(ENOTSUP); }
virtual BAN::ErrorOr<void> fsync_impl() = 0; virtual BAN::ErrorOr<void> fsync_impl() = 0;
// Select/Non blocking API // Select/Non blocking API
virtual bool can_read_impl() const = 0; virtual bool can_read_impl() const = 0;
virtual bool can_write_impl() const = 0; virtual bool can_write_impl() const = 0;
virtual bool has_error_impl() const = 0; virtual bool has_error_impl() const = 0;
virtual bool has_hungup_impl() const = 0;
virtual BAN::ErrorOr<long> ioctl_impl(int, void*) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr<long> ioctl_impl(int, void*) { return BAN::Error::from_errno(ENOTSUP); }
@@ -188,12 +168,9 @@ namespace Kernel
private: private:
BAN::WeakPtr<SharedFileData> m_shared_region; BAN::WeakPtr<SharedFileData> m_shared_region;
SpinLock m_epoll_lock;
BAN::LinkedList<class Epoll*> m_epolls;
friend class Epoll;
friend class FileBackedRegion; friend class FileBackedRegion;
friend class OpenFileDescriptorSet; friend class OpenFileDescriptorSet;
friend struct SharedFileData; friend class SharedFileData;
friend class TTY; friend class TTY;
}; };

View File

@@ -2,7 +2,6 @@
#include <BAN/Array.h> #include <BAN/Array.h>
#include <kernel/FS/Inode.h> #include <kernel/FS/Inode.h>
#include <kernel/Memory/ByteRingBuffer.h>
#include <kernel/ThreadBlocker.h> #include <kernel/ThreadBlocker.h>
namespace Kernel namespace Kernel
@@ -14,9 +13,8 @@ namespace Kernel
static BAN::ErrorOr<BAN::RefPtr<Inode>> create(const Credentials&); static BAN::ErrorOr<BAN::RefPtr<Inode>> create(const Credentials&);
virtual bool is_pipe() const override { return true; } virtual bool is_pipe() const override { return true; }
void clone_writing();
void on_close(int status_flags) override; void close_writing();
void on_clone(int status_flags) override;
virtual ino_t ino() const override { return 0; } // FIXME virtual ino_t ino() const override { return 0; } // FIXME
virtual Mode mode() const override { return { Mode::IFIFO | Mode::IRUSR | Mode::IWUSR }; } virtual Mode mode() const override { return { Mode::IFIFO | Mode::IRUSR | Mode::IWUSR }; }
@@ -39,10 +37,9 @@ namespace Kernel
virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override; virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override;
virtual BAN::ErrorOr<void> fsync_impl() final override { return {}; } virtual BAN::ErrorOr<void> fsync_impl() final override { return {}; }
virtual bool can_read_impl() const override { return !m_buffer->empty(); } virtual bool can_read_impl() const override { return m_buffer_size > 0; }
virtual bool can_write_impl() const override { return true; } virtual bool can_write_impl() const override { return true; }
virtual bool has_error_impl() const override { return m_reading_count == 0; } virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return m_writing_count == 0; }
private: private:
Pipe(const Credentials&); Pipe(const Credentials&);
@@ -55,10 +52,11 @@ namespace Kernel
timespec m_ctime {}; timespec m_ctime {};
ThreadBlocker m_thread_blocker; ThreadBlocker m_thread_blocker;
BAN::UniqPtr<ByteRingBuffer> m_buffer; BAN::Array<uint8_t, PAGE_SIZE> m_buffer;
BAN::Atomic<size_t> m_buffer_size { 0 };
size_t m_buffer_tail { 0 };
BAN::Atomic<uint32_t> m_writing_count { 1 }; BAN::Atomic<uint32_t> m_writing_count { 1 };
BAN::Atomic<uint32_t> m_reading_count { 1 };
}; };
} }

View File

@@ -47,7 +47,6 @@ namespace Kernel
virtual bool can_read_impl() const override { return true; } virtual bool can_read_impl() const override { return true; }
virtual bool can_write_impl() const override { return false; } virtual bool can_write_impl() const override { return false; }
virtual bool has_error_impl() const override { return false; } virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private: private:
ProcROProcessInode(Process&, size_t (Process::*)(off_t, BAN::ByteSpan) const, TmpFileSystem&, const TmpInodeInfo&); ProcROProcessInode(Process&, size_t (Process::*)(off_t, BAN::ByteSpan) const, TmpFileSystem&, const TmpInodeInfo&);
@@ -57,31 +56,6 @@ namespace Kernel
size_t (Process::*m_callback)(off_t, BAN::ByteSpan) const; size_t (Process::*m_callback)(off_t, BAN::ByteSpan) const;
}; };
class ProcSymlinkProcessInode final : public TmpInode
{
public:
static BAN::ErrorOr<BAN::RefPtr<ProcSymlinkProcessInode>> create_new(Process& process, BAN::ErrorOr<BAN::String> (Process::*callback)() const, TmpFileSystem&, mode_t);
~ProcSymlinkProcessInode() = default;
virtual uid_t uid() const override { return m_process.credentials().ruid(); }
virtual gid_t gid() const override { return m_process.credentials().rgid(); }
protected:
virtual BAN::ErrorOr<BAN::String> link_target_impl() override;
virtual bool can_read_impl() const override { return false; }
virtual bool can_write_impl() const override { return false; }
virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private:
ProcSymlinkProcessInode(Process& process, BAN::ErrorOr<BAN::String> (Process::*)() const, TmpFileSystem&, const TmpInodeInfo&);
private:
Process& m_process;
BAN::ErrorOr<BAN::String> (Process::*m_callback)() const;
};
class ProcROInode final : public TmpInode class ProcROInode final : public TmpInode
{ {
public: public:
@@ -98,7 +72,6 @@ namespace Kernel
virtual bool can_read_impl() const override { return true; } virtual bool can_read_impl() const override { return true; }
virtual bool can_write_impl() const override { return false; } virtual bool can_write_impl() const override { return false; }
virtual bool has_error_impl() const override { return false; } virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private: private:
ProcROInode(size_t (*callback)(off_t, BAN::ByteSpan), TmpFileSystem&, const TmpInodeInfo&); ProcROInode(size_t (*callback)(off_t, BAN::ByteSpan), TmpFileSystem&, const TmpInodeInfo&);
@@ -107,57 +80,4 @@ namespace Kernel
size_t (*m_callback)(off_t, BAN::ByteSpan); size_t (*m_callback)(off_t, BAN::ByteSpan);
}; };
class ProcSymlinkInode final : public TmpInode
{
public:
static BAN::ErrorOr<BAN::RefPtr<ProcSymlinkInode>> create_new(BAN::ErrorOr<BAN::String> (*)(void*), void (*)(void*), void* data, TmpFileSystem&, mode_t, uid_t, gid_t);
~ProcSymlinkInode();
protected:
virtual BAN::ErrorOr<BAN::String> link_target_impl() override;
virtual bool can_read_impl() const override { return false; }
virtual bool can_write_impl() const override { return false; }
virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private:
ProcSymlinkInode(BAN::ErrorOr<BAN::String> (*callback)(void*), void (*destructor)(void*), void* data, TmpFileSystem&, const TmpInodeInfo&);
private:
BAN::ErrorOr<BAN::String> (*m_callback)(void*);
void (*m_destructor)(void*);
void* m_data;
};
class ProcFDDirectoryInode final : public TmpInode
{
public:
static BAN::ErrorOr<BAN::RefPtr<ProcFDDirectoryInode>> create_new(Process&, TmpFileSystem&, mode_t);
~ProcFDDirectoryInode() = default;
virtual uid_t uid() const override { return m_process.credentials().ruid(); }
virtual gid_t gid() const override { return m_process.credentials().rgid(); }
protected:
virtual BAN::ErrorOr<BAN::RefPtr<Inode>> find_inode_impl(BAN::StringView) override;
virtual BAN::ErrorOr<size_t> list_next_inodes_impl(off_t, struct dirent*, size_t) override;
virtual BAN::ErrorOr<void> create_file_impl(BAN::StringView, mode_t, uid_t, gid_t) override { return BAN::Error::from_errno(EPERM); }
virtual BAN::ErrorOr<void> create_directory_impl(BAN::StringView, mode_t, uid_t, gid_t) override { return BAN::Error::from_errno(EPERM); }
virtual BAN::ErrorOr<void> link_inode_impl(BAN::StringView, BAN::RefPtr<Inode>) override { return BAN::Error::from_errno(EPERM); }
virtual BAN::ErrorOr<void> rename_inode_impl(BAN::RefPtr<Inode>, BAN::StringView, BAN::StringView) override { return BAN::Error::from_errno(EPERM); }
virtual BAN::ErrorOr<void> unlink_impl(BAN::StringView) override { return BAN::Error::from_errno(EPERM); }
virtual bool can_read_impl() const override { return false; }
virtual bool can_write_impl() const override { return false; }
virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private:
ProcFDDirectoryInode(Process&, TmpFileSystem&, const TmpInodeInfo&);
private:
Process& m_process;
};
} }

View File

@@ -51,6 +51,8 @@ namespace Kernel
: m_info(info) : m_info(info)
{} {}
BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan buffer) override { return recvfrom_impl(buffer, nullptr, nullptr); }
BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan buffer) override { return sendto_impl(buffer, nullptr, 0); }
BAN::ErrorOr<void> fsync_impl() final override { return {}; } BAN::ErrorOr<void> fsync_impl() final override { return {}; }
private: private:

View File

@@ -28,7 +28,7 @@ namespace Kernel
// 1x singly indirect // 1x singly indirect
// 1x doubly indirect // 1x doubly indirect
// 1x triply indirect // 1x triply indirect
BAN::Array<size_t, 5> block; BAN::Array<paddr_t, 5> block;
static constexpr size_t direct_block_count = 2; static constexpr size_t direct_block_count = 2;
#elif ARCH(i686) #elif ARCH(i686)
uint32_t __padding; uint32_t __padding;
@@ -36,8 +36,8 @@ namespace Kernel
// 1x singly indirect // 1x singly indirect
// 1x doubly indirect // 1x doubly indirect
// 1x triply indirect // 1x triply indirect
BAN::Array<size_t, 16> block; BAN::Array<paddr_t, 8> block;
static constexpr size_t direct_block_count = 13; static constexpr size_t direct_block_count = 5;
#else #else
#error #error
#endif #endif

View File

@@ -58,7 +58,7 @@ namespace Kernel
virtual BAN::RefPtr<Inode> root_inode() override { return m_root_inode; } virtual BAN::RefPtr<Inode> root_inode() override { return m_root_inode; }
dev_t rdev() const { return m_rdev; } virtual dev_t dev() const override { return m_rdev; }
BAN::ErrorOr<BAN::RefPtr<TmpInode>> open_inode(ino_t ino); BAN::ErrorOr<BAN::RefPtr<TmpInode>> open_inode(ino_t ino);
@@ -118,8 +118,16 @@ namespace Kernel
private: private:
InodeLocation find_inode(ino_t ino); InodeLocation find_inode(ino_t ino);
paddr_t find_block(size_t index); paddr_t find_block(size_t index);
template<TmpFuncs::for_each_indirect_paddr_allocating_callback F>
BAN::ErrorOr<void> for_each_indirect_paddr_allocating(PageInfo page_info, F callback, size_t depth);
template<TmpFuncs::for_each_indirect_paddr_allocating_callback F>
BAN::ErrorOr<BAN::Iteration> for_each_indirect_paddr_allocating_internal(PageInfo page_info, F callback, size_t depth);
paddr_t find_indirect(PageInfo root, size_t index, size_t depth);
private: private:
const dev_t m_rdev; const dev_t m_rdev;
@@ -138,14 +146,14 @@ namespace Kernel
static constexpr size_t max_data_pages = static constexpr size_t max_data_pages =
(PAGE_SIZE / sizeof(PageInfo)) * (PAGE_SIZE / sizeof(PageInfo)) *
(PAGE_SIZE / sizeof(PageInfo)) * (PAGE_SIZE / sizeof(PageInfo)) *
(PAGE_SIZE / sizeof(PageInfo) - 1); (PAGE_SIZE / sizeof(PageInfo));
// We store inodes in pages with double indirection. // We store inodes in pages with double indirection.
// With 64-bit pointers we can store 512^2 pages of inodes // With 64-bit pointers we can store 512^2 pages of inodes
// which should be enough for now. // which should be enough for now.
// In future this should be dynamically calculated based on maximum // In future this should be dynamically calculated based on maximum
// number of pages for this file system. // number of pages for this file system.
PageInfo m_inode_pages {}; PageInfo m_inode_pages;
static constexpr size_t first_inode = 1; static constexpr size_t first_inode = 1;
static constexpr size_t max_inodes = static constexpr size_t max_inodes =
(PAGE_SIZE / sizeof(PageInfo)) * (PAGE_SIZE / sizeof(PageInfo)) *

View File

@@ -47,22 +47,14 @@ namespace Kernel
protected: protected:
TmpInode(TmpFileSystem&, ino_t, const TmpInodeInfo&); TmpInode(TmpFileSystem&, ino_t, const TmpInodeInfo&);
virtual BAN::ErrorOr<void> chmod_impl(mode_t) override;
virtual BAN::ErrorOr<void> chown_impl(uid_t, gid_t) override;
virtual BAN::ErrorOr<void> utimens_impl(const timespec[2]) override;
virtual BAN::ErrorOr<void> fsync_impl() override { return {}; } virtual BAN::ErrorOr<void> fsync_impl() override { return {}; }
void sync(); void sync();
void free_all_blocks();
virtual BAN::ErrorOr<void> prepare_unlink() { return {}; }; virtual BAN::ErrorOr<void> prepare_unlink() { return {}; };
void free_all_blocks();
void free_indirect_blocks(size_t block, uint32_t depth);
BAN::Optional<size_t> block_index(size_t data_block_index); BAN::Optional<size_t> block_index(size_t data_block_index);
BAN::Optional<size_t> block_index_from_indirect(size_t block, size_t index, uint32_t depth);
BAN::ErrorOr<size_t> block_index_with_allocation(size_t data_block_index); BAN::ErrorOr<size_t> block_index_with_allocation(size_t data_block_index);
BAN::ErrorOr<size_t> block_index_from_indirect_with_allocation(size_t& block, size_t index, uint32_t depth);
protected: protected:
TmpFileSystem& m_fs; TmpFileSystem& m_fs;
@@ -83,11 +75,11 @@ namespace Kernel
virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override; virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override;
virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override; virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override;
virtual BAN::ErrorOr<void> truncate_impl(size_t) override; virtual BAN::ErrorOr<void> truncate_impl(size_t) override;
virtual BAN::ErrorOr<void> chmod_impl(mode_t) override;
virtual bool can_read_impl() const override { return true; } virtual bool can_read_impl() const override { return true; }
virtual bool can_write_impl() const override { return true; } virtual bool can_write_impl() const override { return true; }
virtual bool has_error_impl() const override { return false; } virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private: private:
TmpFileInode(TmpFileSystem&, ino_t, const TmpInodeInfo&); TmpFileInode(TmpFileSystem&, ino_t, const TmpInodeInfo&);
@@ -105,11 +97,11 @@ namespace Kernel
virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override { return BAN::Error::from_errno(ENODEV); } virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) override { return BAN::Error::from_errno(ENODEV); }
virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override { return BAN::Error::from_errno(ENODEV); } virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override { return BAN::Error::from_errno(ENODEV); }
virtual BAN::ErrorOr<void> truncate_impl(size_t) override { return BAN::Error::from_errno(ENODEV); } virtual BAN::ErrorOr<void> truncate_impl(size_t) override { return BAN::Error::from_errno(ENODEV); }
virtual BAN::ErrorOr<void> chmod_impl(mode_t) override;
virtual bool can_read_impl() const override { return false; } virtual bool can_read_impl() const override { return false; }
virtual bool can_write_impl() const override { return false; } virtual bool can_write_impl() const override { return false; }
virtual bool has_error_impl() const override { return false; } virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private: private:
TmpSocketInode(TmpFileSystem&, ino_t, const TmpInodeInfo&); TmpSocketInode(TmpFileSystem&, ino_t, const TmpInodeInfo&);
@@ -123,14 +115,14 @@ namespace Kernel
static BAN::ErrorOr<BAN::RefPtr<TmpSymlinkInode>> create_new(TmpFileSystem&, mode_t, uid_t, gid_t, BAN::StringView target); static BAN::ErrorOr<BAN::RefPtr<TmpSymlinkInode>> create_new(TmpFileSystem&, mode_t, uid_t, gid_t, BAN::StringView target);
~TmpSymlinkInode(); ~TmpSymlinkInode();
BAN::ErrorOr<void> set_link_target(BAN::StringView);
protected: protected:
BAN::ErrorOr<BAN::String> link_target_impl() override; virtual BAN::ErrorOr<BAN::String> link_target_impl() override;
BAN::ErrorOr<void> set_link_target_impl(BAN::StringView) override;
virtual bool can_read_impl() const override { return false; } virtual bool can_read_impl() const override { return false; }
virtual bool can_write_impl() const override { return false; } virtual bool can_write_impl() const override { return false; }
virtual bool has_error_impl() const override { return false; } virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private: private:
TmpSymlinkInode(TmpFileSystem&, ino_t, const TmpInodeInfo&); TmpSymlinkInode(TmpFileSystem&, ino_t, const TmpInodeInfo&);
@@ -156,21 +148,16 @@ namespace Kernel
virtual BAN::ErrorOr<size_t> list_next_inodes_impl(off_t, struct dirent*, size_t) override final; virtual BAN::ErrorOr<size_t> list_next_inodes_impl(off_t, struct dirent*, size_t) override final;
virtual BAN::ErrorOr<void> create_file_impl(BAN::StringView, mode_t, uid_t, gid_t) override final; virtual BAN::ErrorOr<void> create_file_impl(BAN::StringView, mode_t, uid_t, gid_t) override final;
virtual BAN::ErrorOr<void> create_directory_impl(BAN::StringView, mode_t, uid_t, gid_t) override final; virtual BAN::ErrorOr<void> create_directory_impl(BAN::StringView, mode_t, uid_t, gid_t) override final;
virtual BAN::ErrorOr<void> link_inode_impl(BAN::StringView, BAN::RefPtr<Inode>) override final;
virtual BAN::ErrorOr<void> rename_inode_impl(BAN::RefPtr<Inode>, BAN::StringView, BAN::StringView) override final;
virtual BAN::ErrorOr<void> unlink_impl(BAN::StringView) override; virtual BAN::ErrorOr<void> unlink_impl(BAN::StringView) override;
virtual bool can_read_impl() const override { return false; } virtual bool can_read_impl() const override { return false; }
virtual bool can_write_impl() const override { return false; } virtual bool can_write_impl() const override { return false; }
virtual bool has_error_impl() const override { return false; } virtual bool has_error_impl() const override { return false; }
virtual bool has_hungup_impl() const override { return false; }
private: private:
template<TmpFuncs::for_each_valid_entry_callback F> template<TmpFuncs::for_each_valid_entry_callback F>
void for_each_valid_entry(F callback); void for_each_valid_entry(F callback);
BAN::ErrorOr<void> unlink_inode(BAN::StringView, bool cleanup);
friend class TmpInode; friend class TmpInode;
}; };

View File

@@ -1,12 +0,0 @@
#pragma once
#include <kernel/BootInfo.h>
#include <kernel/FS/FileSystem.h>
namespace Kernel
{
bool is_ustar_boot_module(const BootModule&);
BAN::ErrorOr<void> unpack_boot_module_into_filesystem(BAN::RefPtr<FileSystem>, const BootModule&);
}

View File

@@ -29,6 +29,9 @@ namespace Kernel
virtual BAN::RefPtr<Inode> root_inode() override { return m_root_fs->root_inode(); } virtual BAN::RefPtr<Inode> root_inode() override { return m_root_fs->root_inode(); }
// FIXME:
virtual dev_t dev() const override { return 0; }
BAN::ErrorOr<void> mount(const Credentials&, BAN::StringView, BAN::StringView); BAN::ErrorOr<void> mount(const Credentials&, BAN::StringView, BAN::StringView);
BAN::ErrorOr<void> mount(const Credentials&, BAN::RefPtr<FileSystem>, BAN::StringView); BAN::ErrorOr<void> mount(const Credentials&, BAN::RefPtr<FileSystem>, BAN::StringView);
@@ -71,13 +74,13 @@ namespace Kernel
File root_file() File root_file()
{ {
return File { root_inode(), "/"_sv }; return File(root_inode(), "/"_sv);
} }
BAN::ErrorOr<File> file_from_relative_path(BAN::RefPtr<Inode> root_inode, const File& parent, const Credentials&, BAN::StringView, int); BAN::ErrorOr<File> file_from_relative_path(const File& parent, const Credentials&, BAN::StringView, int);
BAN::ErrorOr<File> file_from_absolute_path(BAN::RefPtr<Inode> root_inode, const Credentials& credentials, BAN::StringView path, int flags) BAN::ErrorOr<File> file_from_absolute_path(const Credentials& credentials, BAN::StringView path, int flags)
{ {
return file_from_relative_path(root_inode, File { root_inode, "/"_sv }, credentials, path, flags); return file_from_relative_path(root_file(), credentials, path, flags);
} }
private: private:

View File

@@ -129,8 +129,7 @@ namespace Kernel
} }
#if ARCH(i686) #if ARCH(i686)
void set_fsbase(uintptr_t addr); void set_tls(uintptr_t addr);
void set_gsbase(uintptr_t addr);
#endif #endif
private: private:
@@ -151,11 +150,11 @@ namespace Kernel
private: private:
#if ARCH(x86_64) #if ARCH(x86_64)
BAN::Array<SegmentDescriptor, 8> m_gdt; // null, kernel code, kernel data, user code (32 bit), user data, user code (64 bit), tss low, tss high BAN::Array<SegmentDescriptor, 7> m_gdt; // null, kernel code, kernel data, user code, user data, tss low, tss high
static constexpr uint16_t m_tss_offset = 0x30; static constexpr uint16_t m_tss_offset = 0x28;
#elif ARCH(i686) #elif ARCH(i686)
BAN::Array<SegmentDescriptor, 9> m_gdt; // null, kernel code, kernel data, user code, user data, processor data, fsbase, gsbase, tss BAN::Array<SegmentDescriptor, 8> m_gdt; // null, kernel code, kernel data, user code, user data, processor data, tls, tss
static constexpr uint16_t m_tss_offset = 0x40; static constexpr uint16_t m_tss_offset = 0x38;
#endif #endif
TaskStateSegment m_tss; TaskStateSegment m_tss;
const GDTR m_gdtr { const GDTR m_gdtr {

View File

@@ -18,12 +18,10 @@ namespace Kernel
constexpr uint8_t IRQ_VECTOR_BASE = 0x20; constexpr uint8_t IRQ_VECTOR_BASE = 0x20;
constexpr uint8_t IRQ_MSI_BASE = 0x80; constexpr uint8_t IRQ_MSI_BASE = 0x80;
constexpr uint8_t IRQ_MSI_END = 0xF0;
#if ARCH(i686)
constexpr uint8_t IRQ_SYSCALL = 0xF0; constexpr uint8_t IRQ_SYSCALL = 0xF0;
#endif constexpr uint8_t IRQ_YIELD = 0xF1;
constexpr uint8_t IRQ_IPI = 0xF1; constexpr uint8_t IRQ_IPI = 0xF2;
constexpr uint8_t IRQ_TIMER = 0xF2; constexpr uint8_t IRQ_TIMER = 0xF3;
#if ARCH(x86_64) #if ARCH(x86_64)
struct GateDescriptor struct GateDescriptor
@@ -77,7 +75,7 @@ namespace Kernel
private: private:
IDT() = default; IDT() = default;
void register_interrupt_handler(uint8_t index, void (*handler)(), uint8_t ist = 0); void register_interrupt_handler(uint8_t index, void (*handler)());
void register_syscall_handler(uint8_t index, void (*handler)()); void register_syscall_handler(uint8_t index, void (*handler)());
private: private:

View File

@@ -15,7 +15,6 @@ namespace Kernel
{ {
Mouse, Mouse,
Keyboard, Keyboard,
Joystick,
}; };
public: public:
@@ -32,7 +31,7 @@ namespace Kernel
bool can_read_impl() const override { SpinLockGuard _(m_event_lock); return m_event_count > 0; } bool can_read_impl() const override { SpinLockGuard _(m_event_lock); return m_event_count > 0; }
bool can_write_impl() const override { return false; } bool can_write_impl() const override { return false; }
bool has_error_impl() const override { return false; } bool has_error_impl() const override { return false; }
bool has_hungup_impl() const override { return false; }
private: private:
BAN::ErrorOr<size_t> read_non_block(BAN::ByteSpan); BAN::ErrorOr<size_t> read_non_block(BAN::ByteSpan);
@@ -65,7 +64,7 @@ namespace Kernel
public: public:
static BAN::ErrorOr<BAN::RefPtr<KeyboardDevice>> create(mode_t mode, uid_t uid, gid_t gid); static BAN::ErrorOr<BAN::RefPtr<KeyboardDevice>> create(mode_t mode, uid_t uid, gid_t gid);
void notify(); void notify() { m_thread_blocker.unblock(); }
private: private:
KeyboardDevice(mode_t mode, uid_t uid, gid_t gid); KeyboardDevice(mode_t mode, uid_t uid, gid_t gid);
@@ -74,7 +73,6 @@ namespace Kernel
bool can_read_impl() const override; bool can_read_impl() const override;
bool can_write_impl() const override { return false; } bool can_write_impl() const override { return false; }
bool has_error_impl() const override { return false; } bool has_error_impl() const override { return false; }
bool has_hungup_impl() const override { return false; }
BAN::StringView name() const final override { return m_name; } BAN::StringView name() const final override { return m_name; }
dev_t rdev() const final override { return m_rdev; } dev_t rdev() const final override { return m_rdev; }
@@ -92,7 +90,7 @@ namespace Kernel
public: public:
static BAN::ErrorOr<BAN::RefPtr<MouseDevice>> create(mode_t mode, uid_t uid, gid_t gid); static BAN::ErrorOr<BAN::RefPtr<MouseDevice>> create(mode_t mode, uid_t uid, gid_t gid);
void notify(); void notify() { m_thread_blocker.unblock(); }
private: private:
MouseDevice(mode_t mode, uid_t uid, gid_t gid); MouseDevice(mode_t mode, uid_t uid, gid_t gid);
@@ -101,7 +99,6 @@ namespace Kernel
bool can_read_impl() const override; bool can_read_impl() const override;
bool can_write_impl() const override { return false; } bool can_write_impl() const override { return false; }
bool has_error_impl() const override { return false; } bool has_error_impl() const override { return false; }
bool has_hungup_impl() const override { return false; }
BAN::StringView name() const final override { return m_name; } BAN::StringView name() const final override { return m_name; }
dev_t rdev() const final override { return m_rdev; } dev_t rdev() const final override { return m_rdev; }

View File

@@ -14,15 +14,6 @@ namespace Kernel::Input
class PS2Controller class PS2Controller
{ {
public:
enum class DeviceType
{
None,
Unknown,
Keyboard,
Mouse,
};
public: public:
static BAN::ErrorOr<void> initialize(uint8_t scancode_set); static BAN::ErrorOr<void> initialize(uint8_t scancode_set);
static PS2Controller& get(); static PS2Controller& get();
@@ -33,14 +24,10 @@ namespace Kernel::Input
// Returns true, if byte is used as command, if returns false, byte is meant to device // Returns true, if byte is used as command, if returns false, byte is meant to device
bool handle_command_byte(PS2Device*, uint8_t); bool handle_command_byte(PS2Device*, uint8_t);
uint8_t data_port() const { return m_data_port; }
private: private:
PS2Controller() = default; PS2Controller() = default;
BAN::ErrorOr<void> initialize_impl(uint8_t scancode_set); BAN::ErrorOr<void> initialize_impl(uint8_t scancode_set);
BAN::ErrorOr<DeviceType> identify_device(uint8_t); BAN::ErrorOr<void> initialize_device(uint8_t, uint8_t scancode_set);
void device_initialize_task(void*);
BAN::ErrorOr<uint8_t> read_byte(); BAN::ErrorOr<uint8_t> read_byte();
BAN::ErrorOr<void> send_byte(uint16_t port, uint8_t byte); BAN::ErrorOr<void> send_byte(uint16_t port, uint8_t byte);
@@ -72,9 +59,6 @@ namespace Kernel::Input
}; };
private: private:
uint16_t m_command_port { PS2::IOPort::COMMAND };
uint16_t m_data_port { PS2::IOPort::DATA };
BAN::RefPtr<PS2Device> m_devices[2]; BAN::RefPtr<PS2Device> m_devices[2];
Mutex m_mutex; Mutex m_mutex;

View File

@@ -22,7 +22,6 @@ namespace Kernel::Input
protected: protected:
PS2Device(PS2Controller&, InputDevice::Type type); PS2Device(PS2Controller&, InputDevice::Type type);
virtual ~PS2Device();
protected: protected:
PS2Controller& m_controller; PS2Controller& m_controller;

View File

@@ -27,6 +27,7 @@ namespace Kernel
uintptr_t r10; uintptr_t r10;
uintptr_t r9; uintptr_t r9;
uintptr_t r8; uintptr_t r8;
uintptr_t rdi; uintptr_t rdi;
uintptr_t rsi; uintptr_t rsi;
uintptr_t rbp; uintptr_t rbp;
@@ -35,18 +36,6 @@ namespace Kernel
uintptr_t rcx; uintptr_t rcx;
uintptr_t rax; uintptr_t rax;
}; };
struct YieldRegisters
{
uintptr_t r15;
uintptr_t r14;
uintptr_t r13;
uintptr_t r12;
uintptr_t rbp;
uintptr_t rbx;
uintptr_t ret;
uintptr_t sp;
uintptr_t ip;
};
#elif ARCH(i686) #elif ARCH(i686)
struct InterruptRegisters struct InterruptRegisters
{ {
@@ -59,16 +48,6 @@ namespace Kernel
uintptr_t ecx; uintptr_t ecx;
uintptr_t eax; uintptr_t eax;
}; };
struct YieldRegisters
{
uintptr_t ebp;
uintptr_t edi;
uintptr_t esi;
uintptr_t ebx;
uintptr_t ret;
uintptr_t sp;
uintptr_t ip;
};
#endif #endif
} }

View File

@@ -29,4 +29,30 @@ namespace Kernel
Lock& m_lock; Lock& m_lock;
}; };
template<typename Lock>
class LockFreeGuard
{
BAN_NON_COPYABLE(LockFreeGuard);
BAN_NON_MOVABLE(LockFreeGuard);
public:
LockFreeGuard(Lock& lock)
: m_lock(lock)
, m_depth(lock.lock_depth())
{
for (uint32_t i = 0; i < m_depth; i++)
m_lock.unlock();
}
~LockFreeGuard()
{
for (uint32_t i = 0; i < m_depth; i++)
m_lock.lock();
}
private:
Lock& m_lock;
const uint32_t m_depth;
};
} }

View File

@@ -9,19 +9,7 @@
namespace Kernel namespace Kernel
{ {
class BaseMutex class Mutex
{
public:
virtual void lock() = 0;
virtual bool try_lock() = 0;
virtual void unlock() = 0;
virtual pid_t locker() const = 0;
virtual bool is_locked() const = 0;
virtual uint32_t lock_depth() const = 0;
};
class Mutex : public BaseMutex
{ {
BAN_NON_COPYABLE(Mutex); BAN_NON_COPYABLE(Mutex);
BAN_NON_MOVABLE(Mutex); BAN_NON_MOVABLE(Mutex);
@@ -29,14 +17,13 @@ namespace Kernel
public: public:
Mutex() = default; Mutex() = default;
void lock() override void lock()
{ {
const auto tid = Thread::current_tid(); const auto tid = Thread::current_tid();
if (tid == m_locker) if (tid == m_locker)
ASSERT(m_lock_depth > 0); ASSERT(m_lock_depth > 0);
else else
{ {
ASSERT(!tid || !Thread::current().has_spinlock());
pid_t expected = -1; pid_t expected = -1;
while (!m_locker.compare_exchange(expected, tid)) while (!m_locker.compare_exchange(expected, tid))
{ {
@@ -50,7 +37,7 @@ namespace Kernel
m_lock_depth++; m_lock_depth++;
} }
bool try_lock() override bool try_lock()
{ {
const auto tid = Thread::current_tid(); const auto tid = Thread::current_tid();
if (tid == m_locker) if (tid == m_locker)
@@ -68,7 +55,7 @@ namespace Kernel
return true; return true;
} }
void unlock() override void unlock()
{ {
const auto tid = Thread::current_tid(); const auto tid = Thread::current_tid();
ASSERT(m_locker == tid); ASSERT(m_locker == tid);
@@ -81,16 +68,16 @@ namespace Kernel
} }
} }
pid_t locker() const override { return m_locker; } pid_t locker() const { return m_locker; }
bool is_locked() const override { return m_locker != -1; } bool is_locked() const { return m_locker != -1; }
uint32_t lock_depth() const override { return m_lock_depth; } uint32_t lock_depth() const { return m_lock_depth; }
private: private:
BAN::Atomic<pid_t> m_locker { -1 }; BAN::Atomic<pid_t> m_locker { -1 };
uint32_t m_lock_depth { 0 }; uint32_t m_lock_depth { 0 };
}; };
class PriorityMutex : public BaseMutex class PriorityMutex
{ {
BAN_NON_COPYABLE(PriorityMutex); BAN_NON_COPYABLE(PriorityMutex);
BAN_NON_MOVABLE(PriorityMutex); BAN_NON_MOVABLE(PriorityMutex);
@@ -98,15 +85,13 @@ namespace Kernel
public: public:
PriorityMutex() = default; PriorityMutex() = default;
void lock() override void lock()
{ {
const auto tid = Thread::current_tid(); const auto tid = Thread::current_tid();
if (tid == m_locker) if (tid == m_locker)
ASSERT(m_lock_depth > 0); ASSERT(m_lock_depth > 0);
else else
{ {
ASSERT(!tid || !Thread::current().has_spinlock());
bool has_priority = tid ? !Thread::current().is_userspace() : true; bool has_priority = tid ? !Thread::current().is_userspace() : true;
if (has_priority) if (has_priority)
m_queue_length++; m_queue_length++;
@@ -123,10 +108,9 @@ namespace Kernel
m_lock_depth++; m_lock_depth++;
} }
bool try_lock() override bool try_lock()
{ {
const auto tid = Thread::current_tid(); const auto tid = Thread::current_tid();
if (tid == m_locker) if (tid == m_locker)
ASSERT(m_lock_depth > 0); ASSERT(m_lock_depth > 0);
else else
@@ -145,7 +129,7 @@ namespace Kernel
return true; return true;
} }
void unlock() override void unlock()
{ {
const auto tid = Thread::current_tid(); const auto tid = Thread::current_tid();
ASSERT(m_locker == tid); ASSERT(m_locker == tid);
@@ -161,9 +145,9 @@ namespace Kernel
} }
} }
pid_t locker() const override { return m_locker; } pid_t locker() const { return m_locker; }
bool is_locked() const override { return m_locker != -1; } bool is_locked() const { return m_locker != -1; }
uint32_t lock_depth() const override { return m_lock_depth; } uint32_t lock_depth() const { return m_lock_depth; }
private: private:
BAN::Atomic<pid_t> m_locker { -1 }; BAN::Atomic<pid_t> m_locker { -1 };

View File

@@ -1,97 +0,0 @@
#pragma once
#include <kernel/Lock/Mutex.h>
#include <kernel/Lock/LockGuard.h>
namespace Kernel
{
class RWLock
{
BAN_NON_COPYABLE(RWLock);
BAN_NON_MOVABLE(RWLock);
public:
RWLock() = default;
void rd_lock()
{
LockGuard _(m_mutex);
while (m_writers_waiting > 0 || m_writer_active)
m_thread_blocker.block_indefinite(&m_mutex);
m_readers_active++;
}
void rd_unlock()
{
LockGuard _(m_mutex);
if (--m_readers_active == 0)
m_thread_blocker.unblock();
}
void wr_lock()
{
LockGuard _(m_mutex);
m_writers_waiting++;
while (m_readers_active > 0 || m_writer_active)
m_thread_blocker.block_indefinite(&m_mutex);
m_writers_waiting--;
m_writer_active = true;
}
void wr_unlock()
{
LockGuard _(m_mutex);
m_writer_active = false;
m_thread_blocker.unblock();
}
private:
Mutex m_mutex;
ThreadBlocker m_thread_blocker;
uint32_t m_readers_active { 0 };
uint32_t m_writers_waiting { 0 };
bool m_writer_active { false };
};
class RWLockRDGuard
{
BAN_NON_COPYABLE(RWLockRDGuard);
BAN_NON_MOVABLE(RWLockRDGuard);
public:
RWLockRDGuard(RWLock& lock)
: m_lock(lock)
{
m_lock.rd_lock();
}
~RWLockRDGuard()
{
m_lock.rd_unlock();
}
private:
RWLock& m_lock;
};
class RWLockWRGuard
{
BAN_NON_COPYABLE(RWLockWRGuard);
BAN_NON_MOVABLE(RWLockWRGuard);
public:
RWLockWRGuard(RWLock& lock)
: m_lock(lock)
{
m_lock.wr_lock();
}
~RWLockWRGuard()
{
m_lock.wr_unlock();
}
private:
RWLock& m_lock;
};
}

View File

@@ -18,13 +18,42 @@ namespace Kernel
public: public:
SpinLock() = default; SpinLock() = default;
InterruptState lock(); InterruptState lock()
{
auto state = Processor::get_interrupt_state();
Processor::set_interrupt_state(InterruptState::Disabled);
bool try_lock_interrupts_disabled(); auto id = Processor::current_id().as_u32();
ASSERT(m_locker.load(BAN::MemoryOrder::memory_order_relaxed) != id);
void unlock(InterruptState state); auto expected = PROCESSOR_NONE.as_u32();
while (!m_locker.compare_exchange(expected, id, BAN::MemoryOrder::memory_order_acquire))
{
Processor::pause();
expected = PROCESSOR_NONE.as_u32();
}
uint32_t lock_depth() const { return current_processor_has_lock(); } return state;
}
bool try_lock_interrupts_disabled()
{
ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled);
auto id = Processor::current_id().as_u32();
ASSERT(m_locker.load(BAN::MemoryOrder::memory_order_relaxed) != id);
auto expected = PROCESSOR_NONE.as_u32();
return m_locker.compare_exchange(expected, id, BAN::MemoryOrder::memory_order_acquire);
}
void unlock(InterruptState state)
{
ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled);
ASSERT(current_processor_has_lock());
m_locker.store(PROCESSOR_NONE.as_u32(), BAN::MemoryOrder::memory_order_release);
Processor::set_interrupt_state(state);
}
bool current_processor_has_lock() const bool current_processor_has_lock() const
{ {
@@ -43,13 +72,36 @@ namespace Kernel
public: public:
RecursiveSpinLock() = default; RecursiveSpinLock() = default;
InterruptState lock(); InterruptState lock()
{
auto state = Processor::get_interrupt_state();
Processor::set_interrupt_state(InterruptState::Disabled);
bool try_lock_interrupts_disabled(); auto id = Processor::current_id().as_u32();
void unlock(InterruptState state); ProcessorID::value_type expected = PROCESSOR_NONE.as_u32();
while (!m_locker.compare_exchange(expected, id, BAN::MemoryOrder::memory_order_acq_rel))
{
if (expected == id)
break;
Processor::pause();
expected = PROCESSOR_NONE.as_u32();
}
uint32_t lock_depth() const { return m_lock_depth; } m_lock_depth++;
return state;
}
void unlock(InterruptState state)
{
ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled);
ASSERT(current_processor_has_lock());
ASSERT(m_lock_depth > 0);
if (--m_lock_depth == 0)
m_locker.store(PROCESSOR_NONE.as_u32(), BAN::MemoryOrder::memory_order_release);
Processor::set_interrupt_state(state);
}
bool current_processor_has_lock() const bool current_processor_has_lock() const
{ {
@@ -61,9 +113,6 @@ namespace Kernel
uint32_t m_lock_depth { 0 }; uint32_t m_lock_depth { 0 };
}; };
template<typename Lock>
class SpinLockGuardAsMutex;
template<typename Lock> template<typename Lock>
class SpinLockGuard class SpinLockGuard
{ {
@@ -85,7 +134,6 @@ namespace Kernel
private: private:
Lock& m_lock; Lock& m_lock;
InterruptState m_state; InterruptState m_state;
friend class SpinLockGuardAsMutex<Lock>;
}; };
} }

View File

@@ -1,64 +0,0 @@
#pragma once
#include <kernel/Lock/SpinLock.h>
#include <kernel/Lock/Mutex.h>
namespace Kernel
{
// FIXME: These classes are HACKS to allow passing spinlock
// to unblock functions. Write a better API that either
// allows passing spinlocks or do something cleaner that
// whatever shit this is
template<typename Lock>
class SpinLockAsMutex : public BaseMutex
{
public:
SpinLockAsMutex(Lock& lock, InterruptState state)
: m_lock(lock)
, m_lock_depth(lock.lock_depth())
, m_state(state)
, m_locker(Thread::current_tid())
{
ASSERT(m_lock.current_processor_has_lock());
}
void lock() override
{
m_lock.lock();
m_lock_depth++;
}
bool try_lock() override
{
lock();
return true;
}
void unlock() override
{
m_lock.unlock(--m_lock_depth ? InterruptState::Disabled : m_state);
}
pid_t locker() const override { return is_locked() ? m_locker : -1; }
bool is_locked() const override { return m_lock_depth; }
uint32_t lock_depth() const override { return m_lock_depth; }
private:
SpinLock& m_lock;
uint32_t m_lock_depth { 0 };
InterruptState m_state;
const pid_t m_locker;
};
template<typename Lock>
class SpinLockGuardAsMutex : public SpinLockAsMutex<Lock>
{
public:
SpinLockGuardAsMutex(SpinLockGuard<Lock>& guard)
: SpinLockAsMutex<Lock>(guard.m_lock, guard.m_state)
{}
};
}

View File

@@ -1,76 +0,0 @@
#pragma once
#include <BAN/ByteSpan.h>
#include <BAN/UniqPtr.h>
#include <BAN/Vector.h>
#include <kernel/Memory/Types.h>
namespace Kernel
{
class ByteRingBuffer
{
public:
static BAN::ErrorOr<BAN::UniqPtr<ByteRingBuffer>> create(size_t size);
~ByteRingBuffer();
void push(BAN::ConstByteSpan data)
{
ASSERT(data.size() + m_size <= m_capacity);
uint8_t* buffer_head = reinterpret_cast<uint8_t*>(m_vaddr) + (m_tail + m_size) % m_capacity;
memcpy(buffer_head, data.data(), data.size());
m_size += data.size();
}
void pop(size_t size)
{
ASSERT(size <= m_size);
m_tail = (m_tail + size) % m_capacity;
m_size -= size;
}
void pop_back(size_t size)
{
ASSERT(size <= m_size);
m_size -= size;
}
BAN::ConstByteSpan get_data() const
{
const uint8_t* base = reinterpret_cast<const uint8_t*>(m_vaddr);
return { base + m_tail, m_size };
}
uint8_t front() const
{
ASSERT(!empty());
return reinterpret_cast<const uint8_t*>(m_vaddr)[m_tail];
}
uint8_t back() const
{
ASSERT(!empty());
return reinterpret_cast<const uint8_t*>(m_vaddr)[m_tail + m_size];
}
bool empty() const { return m_size == 0; }
bool full() const { return m_size == m_capacity; }
size_t free() const { return m_capacity - m_size; }
size_t size() const { return m_size; }
size_t capacity() const { return m_capacity; }
private:
ByteRingBuffer(size_t capacity)
: m_capacity(capacity)
{ }
private:
size_t m_size { 0 };
size_t m_tail { 0 };
const size_t m_capacity;
vaddr_t m_vaddr { 0 };
};
}

View File

@@ -27,19 +27,18 @@ namespace Kernel
BAN_NON_MOVABLE(FileBackedRegion); BAN_NON_MOVABLE(FileBackedRegion);
public: public:
static BAN::ErrorOr<BAN::UniqPtr<FileBackedRegion>> create(BAN::RefPtr<Inode>, PageTable&, off_t offset, size_t size, AddressRange address_range, Type, PageTable::flags_t, int status_flags); static BAN::ErrorOr<BAN::UniqPtr<FileBackedRegion>> create(BAN::RefPtr<Inode>, PageTable&, off_t offset, size_t size, AddressRange address_range, Type, PageTable::flags_t);
~FileBackedRegion(); ~FileBackedRegion();
BAN::ErrorOr<void> msync(vaddr_t, size_t, int) override; virtual BAN::ErrorOr<void> msync(vaddr_t, size_t, int) override;
BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) override; virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) override;
BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> split(size_t offset) override;
protected: protected:
BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t vaddr, bool wants_write) override; virtual BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t vaddr, bool wants_write) override;
private: private:
FileBackedRegion(BAN::RefPtr<Inode>, PageTable&, off_t offset, ssize_t size, Type type, PageTable::flags_t flags, int status_flags); FileBackedRegion(BAN::RefPtr<Inode>, PageTable&, off_t offset, ssize_t size, Type flags, PageTable::flags_t page_flags);
private: private:
BAN::RefPtr<Inode> m_inode; BAN::RefPtr<Inode> m_inode;

View File

@@ -11,23 +11,22 @@ namespace Kernel
BAN_NON_MOVABLE(MemoryBackedRegion); BAN_NON_MOVABLE(MemoryBackedRegion);
public: public:
static BAN::ErrorOr<BAN::UniqPtr<MemoryBackedRegion>> create(PageTable&, size_t size, AddressRange, Type, PageTable::flags_t, int status_flags); static BAN::ErrorOr<BAN::UniqPtr<MemoryBackedRegion>> create(PageTable&, size_t size, AddressRange, Type, PageTable::flags_t);
~MemoryBackedRegion(); ~MemoryBackedRegion();
BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) override; virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) override;
BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> split(size_t offset) override;
BAN::ErrorOr<void> msync(vaddr_t, size_t, int) override { return {}; } virtual BAN::ErrorOr<void> msync(vaddr_t, size_t, int) override { return {}; }
// Copy data from buffer into this region // Copy data from buffer into this region
// This can fail if no memory is mapped and no free memory was available // This can fail if no memory is mapped and no free memory was available
BAN::ErrorOr<void> copy_data_to_region(size_t offset_into_region, const uint8_t* buffer, size_t buffer_size); BAN::ErrorOr<void> copy_data_to_region(size_t offset_into_region, const uint8_t* buffer, size_t buffer_size);
protected: protected:
BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t vaddr, bool wants_write) override; virtual BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t vaddr, bool wants_write) override;
private: private:
MemoryBackedRegion(PageTable&, size_t size, Type, PageTable::flags_t, int status_flags); MemoryBackedRegion(PageTable&, size_t size, Type, PageTable::flags_t);
}; };
} }

View File

@@ -1,10 +1,10 @@
#pragma once #pragma once
#include <BAN/UniqPtr.h> #include <BAN/UniqPtr.h>
#include <kernel/Lock/Mutex.h>
#include <kernel/Memory/PageTable.h> #include <kernel/Memory/PageTable.h>
#include <kernel/Memory/Types.h> #include <kernel/Memory/Types.h>
#include <kernel/ThreadBlocker.h>
#include <stddef.h>
namespace Kernel namespace Kernel
{ {
@@ -33,25 +33,15 @@ namespace Kernel
bool contains(vaddr_t address) const; bool contains(vaddr_t address) const;
bool contains_fully(vaddr_t address, size_t size) const; bool contains_fully(vaddr_t address, size_t size) const;
bool overlaps(vaddr_t address, size_t size) const; bool overlaps(vaddr_t address, size_t size) const;
bool is_contained_by(vaddr_t address, size_t size) const;
bool writable() const { return m_flags & PageTable::Flags::ReadWrite; } bool writable() const { return m_flags & PageTable::Flags::ReadWrite; }
size_t size() const { return m_size; } size_t size() const { return m_size; }
vaddr_t vaddr() const { return m_vaddr; } vaddr_t vaddr() const { return m_vaddr; }
int status_flags() const { return m_status_flags; }
Type type() const { return m_type; }
PageTable::flags_t flags() const { return m_flags; }
size_t virtual_page_count() const { return BAN::Math::div_round_up<size_t>(m_size, PAGE_SIZE); } size_t virtual_page_count() const { return BAN::Math::div_round_up<size_t>(m_size, PAGE_SIZE); }
size_t physical_page_count() const { return m_physical_page_count; } size_t physical_page_count() const { return m_physical_page_count; }
void pin();
void unpin();
void wait_not_pinned();
BAN::ErrorOr<void> mprotect(PageTable::flags_t);
virtual BAN::ErrorOr<void> msync(vaddr_t, size_t, int) = 0; virtual BAN::ErrorOr<void> msync(vaddr_t, size_t, int) = 0;
// Returns error if no memory was available // Returns error if no memory was available
@@ -60,26 +50,20 @@ namespace Kernel
BAN::ErrorOr<bool> allocate_page_containing(vaddr_t address, bool wants_write); BAN::ErrorOr<bool> allocate_page_containing(vaddr_t address, bool wants_write);
virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) = 0; virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) = 0;
virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> split(size_t offset) = 0;
protected: protected:
MemoryRegion(PageTable&, size_t size, Type type, PageTable::flags_t flags, int status_flags); MemoryRegion(PageTable&, size_t size, Type type, PageTable::flags_t flags);
BAN::ErrorOr<void> initialize(AddressRange); BAN::ErrorOr<void> initialize(AddressRange);
virtual BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t address, bool wants_write) = 0; virtual BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t address, bool wants_write) = 0;
protected: protected:
PageTable& m_page_table; PageTable& m_page_table;
size_t m_size { 0 }; const size_t m_size;
const Type m_type; const Type m_type;
PageTable::flags_t m_flags; const PageTable::flags_t m_flags;
const int m_status_flags;
vaddr_t m_vaddr { 0 }; vaddr_t m_vaddr { 0 };
size_t m_physical_page_count { 0 }; size_t m_physical_page_count { 0 };
Mutex m_pinned_mutex;
BAN::Atomic<size_t> m_pinned_count { 0 };
ThreadBlocker m_pinned_blocker;
}; };
} }

View File

@@ -112,7 +112,7 @@ namespace Kernel
bool is_page_free(vaddr_t) const; bool is_page_free(vaddr_t) const;
bool is_range_free(vaddr_t, size_t bytes) const; bool is_range_free(vaddr_t, size_t bytes) const;
bool reserve_page(vaddr_t, bool only_free = true, bool send_smp_message = true); bool reserve_page(vaddr_t, bool only_free = true);
bool reserve_range(vaddr_t, size_t bytes, bool only_free = true); bool reserve_range(vaddr_t, size_t bytes, bool only_free = true);
vaddr_t reserve_free_page(vaddr_t first_address, vaddr_t last_address = UINTPTR_MAX); vaddr_t reserve_free_page(vaddr_t first_address, vaddr_t last_address = UINTPTR_MAX);
@@ -133,7 +133,7 @@ namespace Kernel
void map_kernel_memory(); void map_kernel_memory();
void prepare_fast_page(); void prepare_fast_page();
void invalidate(vaddr_t, bool send_smp_message); static void invalidate(vaddr_t, bool send_smp_message);
static void map_fast_page(paddr_t); static void map_fast_page(paddr_t);
static void unmap_fast_page(); static void unmap_fast_page();

View File

@@ -6,8 +6,6 @@
#include <kernel/Lock/SpinLock.h> #include <kernel/Lock/SpinLock.h>
#include <kernel/Memory/MemoryRegion.h> #include <kernel/Memory/MemoryRegion.h>
#include <fcntl.h>
namespace Kernel namespace Kernel
{ {
@@ -57,17 +55,15 @@ namespace Kernel
public: public:
static BAN::ErrorOr<BAN::UniqPtr<SharedMemoryObject>> create(BAN::RefPtr<SharedMemoryObjectManager::Object>, PageTable&, AddressRange); static BAN::ErrorOr<BAN::UniqPtr<SharedMemoryObject>> create(BAN::RefPtr<SharedMemoryObjectManager::Object>, PageTable&, AddressRange);
BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) override; virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) override;
BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> split(size_t offset) override; virtual BAN::ErrorOr<void> msync(vaddr_t, size_t, int) override { return {}; }
BAN::ErrorOr<void> msync(vaddr_t, size_t, int) override { return {}; }
protected: protected:
BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t vaddr, bool wants_write) override; virtual BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t vaddr, bool wants_write) override;
private: private:
SharedMemoryObject(BAN::RefPtr<SharedMemoryObjectManager::Object> object, PageTable& page_table) SharedMemoryObject(BAN::RefPtr<SharedMemoryObjectManager::Object> object, PageTable& page_table)
: MemoryRegion(page_table, object->size, MemoryRegion::Type::SHARED, object->flags, O_EXEC | O_RDWR) : MemoryRegion(page_table, object->size, MemoryRegion::Type::SHARED, object->flags)
, m_object(object) , m_object(object)
{ } { }

View File

@@ -4,7 +4,7 @@
#if ARCH(x86_64) #if ARCH(x86_64)
#define KERNEL_OFFSET 0xFFFFFFFF80000000 #define KERNEL_OFFSET 0xFFFFFFFF80000000
#define USERSPACE_END 0x800000000000 #define USERSPACE_END 0xFFFF800000000000
#elif ARCH(i686) #elif ARCH(i686)
#define KERNEL_OFFSET 0xC0000000 #define KERNEL_OFFSET 0xC0000000
#define USERSPACE_END 0xC0000000 #define USERSPACE_END 0xC0000000
@@ -12,7 +12,6 @@
#error #error
#endif #endif
#undef PAGE_SIZE
#define PAGE_SIZE ((uintptr_t)4096) #define PAGE_SIZE ((uintptr_t)4096)
#define PAGE_SIZE_SHIFT 12 #define PAGE_SIZE_SHIFT 12
#define PAGE_ADDR_MASK (~(uintptr_t)0xFFF) #define PAGE_ADDR_MASK (~(uintptr_t)0xFFF)

View File

@@ -15,21 +15,21 @@ namespace Kernel
public: public:
// Create virtual range to fixed virtual address // Create virtual range to fixed virtual address
static BAN::ErrorOr<BAN::UniqPtr<VirtualRange>> create_to_vaddr(PageTable&, vaddr_t, size_t, PageTable::flags_t flags, bool preallocate_pages, bool add_guard_pages); static BAN::ErrorOr<BAN::UniqPtr<VirtualRange>> create_to_vaddr(PageTable&, vaddr_t, size_t, PageTable::flags_t flags, bool preallocate_pages);
// Create virtual range to virtual address range // Create virtual range to virtual address range
static BAN::ErrorOr<BAN::UniqPtr<VirtualRange>> create_to_vaddr_range(PageTable&, vaddr_t vaddr_start, vaddr_t vaddr_end, size_t, PageTable::flags_t flags, bool preallocate_pages, bool add_guard_pages); static BAN::ErrorOr<BAN::UniqPtr<VirtualRange>> create_to_vaddr_range(PageTable&, vaddr_t vaddr_start, vaddr_t vaddr_end, size_t, PageTable::flags_t flags, bool preallocate_pages);
~VirtualRange(); ~VirtualRange();
BAN::ErrorOr<BAN::UniqPtr<VirtualRange>> clone(PageTable&); BAN::ErrorOr<BAN::UniqPtr<VirtualRange>> clone(PageTable&);
vaddr_t vaddr() const { return m_vaddr + (m_has_guard_pages ? PAGE_SIZE : 0); } vaddr_t vaddr() const { return m_vaddr; }
size_t size() const { return m_size - (m_has_guard_pages ? 2 * PAGE_SIZE : 0); } size_t size() const { return m_size; }
PageTable::flags_t flags() const { return m_flags; } PageTable::flags_t flags() const { return m_flags; }
paddr_t paddr_of(vaddr_t vaddr) const paddr_t paddr_of(vaddr_t vaddr) const
{ {
ASSERT(vaddr % PAGE_SIZE == 0); ASSERT(vaddr % PAGE_SIZE == 0);
const size_t index = (vaddr - this->vaddr()) / PAGE_SIZE; const size_t index = (vaddr - m_vaddr) / PAGE_SIZE;
ASSERT(index < m_paddrs.size()); ASSERT(index < m_paddrs.size());
const paddr_t paddr = m_paddrs[index]; const paddr_t paddr = m_paddrs[index];
ASSERT(paddr); ASSERT(paddr);
@@ -38,16 +38,15 @@ namespace Kernel
bool contains(vaddr_t address) const { return vaddr() <= address && address < vaddr() + size(); } bool contains(vaddr_t address) const { return vaddr() <= address && address < vaddr() + size(); }
BAN::ErrorOr<bool> allocate_page_for_demand_paging(vaddr_t address); BAN::ErrorOr<void> allocate_page_for_demand_paging(vaddr_t address);
private: private:
VirtualRange(PageTable&, bool preallocated, bool has_guard_pages, vaddr_t, size_t, PageTable::flags_t); VirtualRange(PageTable&, bool preallocated, vaddr_t, size_t, PageTable::flags_t);
BAN::ErrorOr<void> initialize(); BAN::ErrorOr<void> initialize();
private: private:
PageTable& m_page_table; PageTable& m_page_table;
const bool m_preallocated; const bool m_preallocated;
const bool m_has_guard_pages;
const vaddr_t m_vaddr; const vaddr_t m_vaddr;
const size_t m_size; const size_t m_size;
const PageTable::flags_t m_flags; const PageTable::flags_t m_flags;

Some files were not shown because too many files have changed in this diff Show More