mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-07-01 18:39:16 +00:00
Compare commits
485 Commits
Kernel-mul
...
nightly
Author | SHA1 | Date | |
---|---|---|---|
2c1d6c2608
|
|||
97a892d114
|
|||
3be150da53
|
|||
455224ceb4
|
|||
e01f1dc97c
|
|||
76113df5a9
|
|||
1addd310ad
|
|||
3d92a87bef
|
|||
f7177f92cf
|
|||
6a6c3bfc67
|
|||
8dbeee4d9a
|
|||
5d5b674aed
|
|||
31bbc29c9f
|
|||
f5c8ae9323
|
|||
154d857c2e
|
|||
12ae5a83da
|
|||
13ce994edf
|
|||
814175ddaf
|
|||
43e7ddb9de
|
|||
0187fa5b66
|
|||
33c284091d
|
|||
9538589c11
|
|||
905b6933c9
|
|||
07d0ca0438
|
|||
7d37f8a8a1
|
|||
8103caa52c
|
|||
4929b76c7c
|
|||
d20d4f7bf9
|
|||
f06c0b19fa
|
|||
70a08e46bd
|
|||
2349610e47
|
|||
fda5ede37f
|
|||
81da8dd989
|
|||
557c7e6235
|
|||
83a7f83f81
|
|||
6592db3f4e
|
|||
d7abd36717
|
|||
7873d0e724
|
|||
9626ec4662
|
|||
dbb5a483e0
|
|||
aca55f993f
|
|||
41fe55fd1f
|
|||
c491351fd0
|
|||
75d51fb9d9
|
|||
21db83b943
|
|||
fa2e37f603
|
|||
fab3be67ee
|
|||
6e26184a04
|
|||
6b6028434d
|
|||
ca02557df4
|
|||
527ad803d3
|
|||
2791a602b5
|
|||
3404bbc3bc
|
|||
c254b96256
|
|||
1e4d404a43
|
|||
16ec6cbdb6
|
|||
ba99275700
|
|||
80c313b02d
|
|||
fe8682aa85
|
|||
cd23c59c46
|
|||
f5c9b561a9
|
|||
366fd97c0a
|
|||
d3fd61c068
|
|||
0a037f1ae1
|
|||
292bfa362a
|
|||
bcc2c9d0ab
|
|||
e270c9f35b
|
|||
7902726239
|
|||
abb7899a9d
|
|||
8c4c8d36de
|
|||
0fffc6c914
|
|||
34e24df7c9
|
|||
550e98e87c
|
|||
4ff6790072
|
|||
205ddb1e49
|
|||
0735743f44
|
|||
33eee9c628
|
|||
ef5d61df9d
|
|||
11d326b693
|
|||
5293bb2039
|
|||
bc84c406d9
|
|||
ed1f4f3c1b
|
|||
ec04e5abe9
|
|||
5ecfffc049
|
|||
c7d501b466
|
|||
1f646d6826
|
|||
3315d79742
|
|||
a1b58bacd8
|
|||
69122746de
|
|||
764dfe67a5
|
|||
3d87345a51
|
|||
eb89b060f6
|
|||
25713e0f13
|
|||
03147b532c
|
|||
d8cd27196d
|
|||
832833a56f
|
|||
a4e5f4785c
|
|||
a268f8dc2f
|
|||
a16a88b5f9
|
|||
2d2d28689c
|
|||
d4346202ca
|
|||
b1a30059ed
|
|||
58accf8acf
|
|||
24c0848797
|
|||
b232dc6b40
|
|||
120d67fb1a
|
|||
f6eb4bd3dc
|
|||
7e7e475dac
|
|||
23d0056098
|
|||
3edb4b4761
|
|||
fd24431eea
|
|||
5c1c26b135
|
|||
a333d8aa7c
|
|||
f054e9976a
|
|||
f87c3d7e11
|
|||
0041300a00
|
|||
fe6d7f4b08
|
|||
a1622cc885
|
|||
bd32020876
|
|||
44323c85a3
|
|||
027d77ed66
|
|||
bbb70eb621
|
|||
1593e3107d
|
|||
1a48d05042
|
|||
75dd958316
|
|||
cccbfd2c95
|
|||
bf20bd89ed
|
|||
c3fd55bb00
|
|||
c660a7fe4f
|
|||
91ad0e14df
|
|||
a6ca98987e
|
|||
f8f08a11db
|
|||
5d64c05446
|
|||
a1064d8978
|
|||
6d01cf4e69
|
|||
ffd992cd74
|
|||
8d71ed0ad5
|
|||
93d897e95c
|
|||
31181d5b5d
|
|||
2f18d390e4
|
|||
5ffb0e704d
|
|||
ad0c1e15e0
|
|||
b74d4db23b
|
|||
022d99f795
|
|||
3482131b3f
|
|||
0a32c19923
|
|||
36c5c8ad67
|
|||
6240d6638f
|
|||
7491f19f9a
|
|||
13d52897b8
|
|||
4cc058ab42
|
|||
a7f754c5e8
|
|||
9304cafe0c
|
|||
7b42b46942
|
|||
2ce0e0ed79
|
|||
d69eb73a59
|
|||
aa8f415b98
|
|||
ec792f1fe2
|
|||
4c31568329
|
|||
e9dd70c6c4
|
|||
4e9d25143e
|
|||
92fe4bdd81
|
|||
0b21c57ee5
|
|||
c412a75f91
|
|||
0cc4d5096b
|
|||
34bd348f25
|
|||
d251d9d03f | |||
8f88d9028e | |||
fcdc26c1f7 | |||
fc588f10bc | |||
527e1708ce | |||
1286c4cd90 | |||
0d8c65e44b | |||
27356b7826 | |||
d06b6d3270 | |||
f9476d8c57 | |||
79f2faf55b | |||
2d0245f2ac | |||
79e55140e3 | |||
ae7f39d0de | |||
be72d2dc06 | |||
a8e4dd08bb | |||
c2e31827d8 | |||
7087ce7ec5 | |||
36bb7b7a88 | |||
2080d1f2b7 | |||
b05a6a14e8 | |||
c4225f7bdf | |||
76b3d30db9 | |||
e89e984ccb | |||
dd1ffe0d17 | |||
3feb4e72aa | |||
a43fac0c2d | |||
67a3527e29 | |||
f4a96e0b2e | |||
7e69b8f82a | |||
8258d40115 | |||
568dffbca1 | |||
9a82d812d6 | |||
49ee634822 | |||
babf792c30 | |||
65f9a805e2 | |||
6e077acc66 | |||
5af9c9b0a2 | |||
201ace7eec | |||
40f46312f8 | |||
a53d41008c | |||
8a6910bf04 | |||
1d7a9edd46 | |||
58477bae6a | |||
cbc6238d9d | |||
9f393754f6 | |||
fc43512c75 | |||
551853c5d6 | |||
6b4faf9f78 | |||
4a6cf4f2e5 | |||
b008b8089c | |||
2f33ea4dfd | |||
87540ab0b9 | |||
88a3b0912b | |||
7ec85e67df | |||
67692f2cef | |||
cc81facf50 | |||
95cc190b54 | |||
1c842ef3d1 | |||
27ad61fa17 | |||
45d34c688f | |||
1ff62e22bf | |||
2c02da7eaf | |||
8ef7a25728 | |||
b4cc1d9e66 | |||
793ccfd5ba | |||
66362ed387 | |||
11e7d8c2dd | |||
e1e9ce050d | |||
92610b6678 | |||
15a9a21448 | |||
d4c4016c7c | |||
19055409cd | |||
839dfb74b2 | |||
0bfb45020f | |||
9e746c52bc | |||
3740b65263 | |||
77e51a6f2c | |||
42b8b6895f | |||
9da2650486 | |||
e01f488768 | |||
958a3ed263 | |||
a0e3993a3f | |||
edeecf7831 | |||
90fb9c7952 | |||
0a52ef4f68 | |||
5e0a80fa1c | |||
784f3c3df9 | |||
68acf428a2 | |||
9105c63465 | |||
659805960b | |||
451c5405e0 | |||
bd02b976a2 | |||
9bffe3e013 | |||
84298fc4eb | |||
87a2dc9444 | |||
426a84a1a9 | |||
8eed8909da | |||
09d0af1ea6 | |||
7b85636f8f | |||
95585fce5f | |||
bf1e3432d7 | |||
f824df9aad | |||
426499090e | |||
1af2cf657d | |||
f31d11f7ad | |||
851a8c140f | |||
ae2617dca2 | |||
adba9cc348 | |||
232e06f8f3 | |||
aea8a7bb08 | |||
65ab83b42b | |||
d3f6d51ed2 | |||
ca8dc6429b | |||
cfb5d9a0f4 | |||
8dab45ecfd | |||
88a5f06325 | |||
aab84cd3ab | |||
a3719eef3e | |||
0769a82f4b | |||
f978f2487e | |||
8859bfc438 | |||
5202601c4f | |||
78141b28c7 | |||
3f2584ac09 | |||
a2ce579a61 | |||
0958cdf7f8 | |||
7f3b2b4dbb | |||
f6f46d1bbe | |||
c12ee67592 | |||
74ff9579f3 | |||
d7cbeb9eba | |||
4d333f94bc | |||
e003af38ff | |||
d1c504f9a6 | |||
d46ed57dd7 | |||
a6d372aaad | |||
b3e0b30147 | |||
93e57f5dbe | |||
db5a42289a | |||
77136acccd | |||
258ac6e2f6 | |||
fbe4b94805 | |||
2c2e7d9de3 | |||
9dfa750444 | |||
4240183fa1 | |||
42f26787fb | |||
8d08ab933a | |||
c83c542f5b | |||
08319ef4c7 | |||
f4168e2815 | |||
123d11e4e3 | |||
b1a107fb65 | |||
d375acd0ec | |||
5e6e63ab1a | |||
ab4bc55270 | |||
e5acf4a99e | |||
5089cfa81b | |||
b5fce27037 | |||
0238f62894 | |||
ce59b6ea03 | |||
9dcb5abe89 | |||
4ac29bbce1 | |||
155f3bfab5 | |||
e960f9fcc8 | |||
4bb8ce6d00 | |||
2ae18af9a0 | |||
e61b5824db | |||
0f9a1915d1 | |||
6dfefc90c4 | |||
c688bd7a97 | |||
e927d93a48 | |||
d9235c6f90 | |||
afa87ec5f3 | |||
22d01c7a51 | |||
dfe9bbdbfa | |||
92ef18b412 | |||
d0a8d9dd62 | |||
f3e145e6f7 | |||
d9433256ab | |||
ade1c77361 | |||
3e656854bc | |||
6c3eefa85d | |||
2384791793 | |||
97af4d855f | |||
b0f0982fd4 | |||
bd1d117283 | |||
a1b040360c | |||
8f7938a1e5 | |||
b05868d120 | |||
24fd486764 | |||
23a17fae00 | |||
d7bccb6948 | |||
833d8d497a | |||
1b55332027 | |||
cbe651d2da | |||
9c9f5549d7 | |||
655a2d88f5 | |||
cd49a219df | |||
48067d8f58 | |||
c2412fe710 | |||
2f71bccef2 | |||
f5a813380b | |||
b54a32ba7a | |||
1c5c0b524e | |||
62e482facb | |||
1824c99ca0 | |||
e8b61e6d7f | |||
69bc044b09 | |||
c86d24030e | |||
4ced264c3c | |||
a25c5f4a96 | |||
c0acbf8790 | |||
7ce73ab813 | |||
0ab1833034 | |||
495a0ea609 | |||
72232d8bd2 | |||
6bd705f06a | |||
0912d4b383 | |||
4350393610 | |||
a8ff50541a | |||
a4c5ab7ef3 | |||
e147e1eff5 | |||
c09bdee89a | |||
3fa7acb116 | |||
749a1b1810 | |||
210e06429c | |||
137f16bc55 | |||
995ef471ab | |||
58f3442c6d | |||
3af04bce80 | |||
75c8dbd31b | |||
fbe9fbfbd1 | |||
e6933acfb0 | |||
07abdd9f6c | |||
9cb66f395b | |||
eb602e12c2 | |||
61b1e95629 | |||
2bb997597e | |||
463d16f8bc | |||
6cf3c62c83 | |||
3a85a5586f | |||
363200d443 | |||
d4001003a3 | |||
8bfed94ba9 | |||
04edfd46bb | |||
082f2fb6f2 | |||
94cdd71e1e | |||
c22c079628 | |||
6024a2347b | |||
c723a5f82d | |||
a6d2d51870 | |||
fb186f6615 | |||
0160fa3c72 | |||
d77d6892a0 | |||
2b1ec40dc3 | |||
a1fa698bc3 | |||
4c0cb59aa7 | |||
f015ff606f | |||
df0c17b50f | |||
9a9ee7e571 | |||
e7e248bc3a | |||
bbc6212cfa | |||
170922e1be | |||
100927547d | |||
073f582752 | |||
edd13c30c5 | |||
6dae34debd | |||
dea36a0228 | |||
8dd3179aaa | |||
0699d7962d | |||
e4403cdbd6 | |||
5632c7cb10 | |||
efb3a80ffd | |||
5d3bb391a4 | |||
b3f304f2c5 | |||
e23e793574 | |||
522158913f | |||
12a768a592 | |||
9ea2f4266e | |||
eb7c13dd45 | |||
8f04f8a374 | |||
1695418dcb | |||
b208862de2 | |||
a8481d4260 | |||
c84757af48 | |||
80afbedf39 | |||
911caf7203 | |||
95a8d6fb6f | |||
b471645743 | |||
cc6ec04814 | |||
1dbee4660e | |||
81af8a48cb | |||
0807ea5a9a
|
|||
79d267631a
|
|||
cbd671292d
|
|||
37c3ee8e99
|
|||
7d85dd5dd8
|
|||
17abdcaf1e
|
|||
f038f6110e
|
|||
3798ec0f58
|
|||
fe5e4e3eec
|
|||
6f17b29963
|
|||
8b026175bb
|
|||
828dab1875
|
|||
7948d0c6e5
|
|||
ce3cf8162a
|
|||
640b902045
|
|||
0dbdacb8df
|
|||
220238eff8
|
|||
360afdbc9c
|
|||
f34a222bf1
|
|||
1b1d3e68fd
|
|||
f11c00a4e3
|
|||
ae07b07964
|
|||
23853cbb15
|
|||
00a37325f6
|
|||
ce4ebaf6c5
|
|||
5806c4feaf
|
127
.devcontainer/Dockerfile
Normal file
127
.devcontainer/Dockerfile
Normal file
@ -0,0 +1,127 @@
|
||||
FROM mcr.microsoft.com/devcontainers/cpp:1-ubuntu-24.04
|
||||
|
||||
ARG REINSTALL_CMAKE_VERSION_FROM_SOURCE="none"
|
||||
|
||||
COPY ./reinstall-cmake.sh /tmp/
|
||||
RUN <<EOF
|
||||
if [ "${REINSTALL_CMAKE_VERSION_FROM_SOURCE}" != "none" ]; then
|
||||
chmod +x /tmp/reinstall-cmake.sh && /tmp/reinstall-cmake.sh ${REINSTALL_CMAKE_VERSION_FROM_SOURCE};
|
||||
fi
|
||||
rm -f /tmp/reinstall-cmake.sh
|
||||
EOF
|
||||
|
||||
# Update system and set noninteractive env
|
||||
RUN export DEBIAN_FRONTEND=noninteractive && apt-get update
|
||||
|
||||
# Required packages for building gcc & binutils
|
||||
RUN apt-get -y install --no-install-recommends \
|
||||
build-essential \
|
||||
bison \
|
||||
flex \
|
||||
libgmp-dev \
|
||||
libmpfr-dev \
|
||||
texinfo \
|
||||
file \
|
||||
python3-dev
|
||||
|
||||
# Required packages for building qemu
|
||||
RUN apt-get -y install --no-install-recommends \
|
||||
git \
|
||||
libglib2.0-dev \
|
||||
libfdt-dev \
|
||||
libpixman-1-dev \
|
||||
zlib1g-dev \
|
||||
ninja-build \
|
||||
libaio-dev \
|
||||
libbluetooth-dev \
|
||||
libcapstone-dev \
|
||||
libbrlapi-dev \
|
||||
libbz2-dev \
|
||||
libcap-ng-dev \
|
||||
libcurl4-gnutls-dev \
|
||||
libgtk-3-dev \
|
||||
libibverbs-dev \
|
||||
libjpeg8-dev \
|
||||
libncurses5-dev \
|
||||
libnuma-dev \
|
||||
librbd-dev \
|
||||
librdmacm-dev \
|
||||
libsasl2-dev \
|
||||
libsdl2-dev \
|
||||
libseccomp-dev \
|
||||
libsnappy-dev \
|
||||
libssh-dev \
|
||||
libvde-dev \
|
||||
libvdeplug-dev \
|
||||
libvte-2.91-dev \
|
||||
libxen-dev \
|
||||
liblzo2-dev \
|
||||
valgrind \
|
||||
xfslibs-dev \
|
||||
libnfs-dev \
|
||||
libiscsi-dev \
|
||||
python3-venv \
|
||||
libslirp-dev \
|
||||
ovmf
|
||||
|
||||
# Required packages for building test apps in userspace
|
||||
RUN apt-get -y install --no-install-recommends \
|
||||
mingw-w64 \
|
||||
libtool \
|
||||
libltdl-dev
|
||||
|
||||
# Required packages for building the OS and misc
|
||||
RUN apt-get -y install --no-install-recommends \
|
||||
grub2-common \
|
||||
xorriso \
|
||||
mtools \
|
||||
grub-common \
|
||||
grub-efi-amd64-bin \
|
||||
grub-efi-amd64-signed \
|
||||
grub-gfxpayload-lists \
|
||||
grub-pc-bin \
|
||||
grub-pc \
|
||||
grub2-common \
|
||||
pip \
|
||||
cmake
|
||||
|
||||
# Install git-cliff
|
||||
RUN pip install git-cliff --break-system-packages
|
||||
|
||||
# Install meson
|
||||
RUN pip install meson --break-system-packages
|
||||
|
||||
# Configure git
|
||||
RUN <<EOF
|
||||
git config --global advice.detachedHead false
|
||||
git config --global core.autocrlf input
|
||||
git config --global init.defaultbranch master
|
||||
EOF
|
||||
|
||||
# Set display environment variable for QEMU
|
||||
ENV DISPLAY=:0
|
||||
ENV NO_AT_BRIDGE=1
|
||||
|
||||
# Set PATH
|
||||
RUN <<EOF
|
||||
echo PATH=$PATH:/workspaces/Fennix/cross/bin >> /etc/profile
|
||||
EOF
|
||||
|
||||
ENV CHMOD_KVM=1
|
||||
|
||||
# Remove autoconf & automake
|
||||
RUN sudo apt-get -y remove autoconf automake
|
||||
|
||||
# Required packages for building gcc & binutils
|
||||
RUN <<EOF
|
||||
wget https://launchpad.net/ubuntu/+archive/primary/+files/autoconf_2.69-11.1_all.deb -O /tmp/autoconf.deb
|
||||
sudo dpkg --force-all -i /tmp/autoconf.deb
|
||||
EOF
|
||||
|
||||
# Required packages for building gcc & binutils
|
||||
RUN <<EOF
|
||||
wget https://ftp.gnu.org/gnu/automake/automake-1.15.1.tar.gz -O /tmp/automake.tar.gz
|
||||
tar -xzf /tmp/automake.tar.gz -C /tmp
|
||||
cd /tmp/automake-1.15.1
|
||||
./configure && make && sudo make install
|
||||
EOF
|
45
.devcontainer/devcontainer.json
Normal file
45
.devcontainer/devcontainer.json
Normal file
@ -0,0 +1,45 @@
|
||||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||
// README at: https://github.com/devcontainers/templates/tree/main/src/cpp
|
||||
{
|
||||
"name": "Fennix",
|
||||
"build": {
|
||||
"dockerfile": "Dockerfile"
|
||||
},
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"ms-azuretools.vscode-docker",
|
||||
"eamodio.gitlens",
|
||||
"EditorConfig.EditorConfig",
|
||||
"naumovs.color-highlight",
|
||||
"Gruntfuggly.todo-tree",
|
||||
"ms-vscode.hexeditor",
|
||||
"vivaxy.vscode-conventional-commits",
|
||||
"webfreak.debug",
|
||||
"maziac.asm-code-lens",
|
||||
"Seven1bit.vscode-ext-ansi-color-highlight",
|
||||
"ms-vsliveshare.vsliveshare",
|
||||
"maziac.hex-hover-converter",
|
||||
"ms-vscode.makefile-tools"
|
||||
]
|
||||
}
|
||||
},
|
||||
// From this line below are for qemu, so not that important.
|
||||
"initializeCommand": "[ -x \"$(command -v xhost)\" ] && xhost +local:docker || true", // "xhost -local:docker" to disable
|
||||
"mounts": [
|
||||
{
|
||||
"source": "/tmp/.X11-unix",
|
||||
"target": "/tmp/.X11-unix",
|
||||
"type": "bind"
|
||||
},
|
||||
{
|
||||
"source": "/run/user/1000/pulse/native",
|
||||
"target": "/run/user/1000/pulse/native",
|
||||
"type": "bind"
|
||||
}
|
||||
],
|
||||
"runArgs": [
|
||||
"--privileged",
|
||||
"--network=host"
|
||||
]
|
||||
}
|
59
.devcontainer/reinstall-cmake.sh
Normal file
59
.devcontainer/reinstall-cmake.sh
Normal file
@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env bash
|
||||
#-------------------------------------------------------------------------------------------------------------
|
||||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
|
||||
#-------------------------------------------------------------------------------------------------------------
|
||||
#
|
||||
set -e
|
||||
|
||||
CMAKE_VERSION=${1:-"none"}
|
||||
|
||||
if [ "${CMAKE_VERSION}" = "none" ]; then
|
||||
echo "No CMake version specified, skipping CMake reinstallation"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Cleanup temporary directory and associated files when exiting the script.
|
||||
cleanup() {
|
||||
EXIT_CODE=$?
|
||||
set +e
|
||||
if [[ -n "${TMP_DIR}" ]]; then
|
||||
echo "Executing cleanup of tmp files"
|
||||
rm -Rf "${TMP_DIR}"
|
||||
fi
|
||||
exit $EXIT_CODE
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
|
||||
echo "Installing CMake..."
|
||||
apt-get -y purge --auto-remove cmake
|
||||
mkdir -p /opt/cmake
|
||||
|
||||
architecture=$(dpkg --print-architecture)
|
||||
case "${architecture}" in
|
||||
arm64)
|
||||
ARCH=aarch64 ;;
|
||||
amd64)
|
||||
ARCH=x86_64 ;;
|
||||
*)
|
||||
echo "Unsupported architecture ${architecture}."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
CMAKE_BINARY_NAME="cmake-${CMAKE_VERSION}-linux-${ARCH}.sh"
|
||||
CMAKE_CHECKSUM_NAME="cmake-${CMAKE_VERSION}-SHA-256.txt"
|
||||
TMP_DIR=$(mktemp -d -t cmake-XXXXXXXXXX)
|
||||
|
||||
echo "${TMP_DIR}"
|
||||
cd "${TMP_DIR}"
|
||||
|
||||
curl -sSL "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/${CMAKE_BINARY_NAME}" -O
|
||||
curl -sSL "https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/${CMAKE_CHECKSUM_NAME}" -O
|
||||
|
||||
sha256sum -c --ignore-missing "${CMAKE_CHECKSUM_NAME}"
|
||||
sh "${TMP_DIR}/${CMAKE_BINARY_NAME}" --prefix=/opt/cmake --skip-license
|
||||
|
||||
ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake
|
||||
ln -s /opt/cmake/bin/ctest /usr/local/bin/ctest
|
26
.editorconfig
Normal file
26
.editorconfig
Normal file
@ -0,0 +1,26 @@
|
||||
# EditorConfig is awesome: https://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
|
||||
[.github/**]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[{CMakeLists.txt,*.cmake}]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
||||
[*.md]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
trim_trailing_whitespace = false
|
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@ -3,7 +3,7 @@
|
||||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: # Replace with a single Patreon username
|
||||
open_collective: # Replace with a single Open Collective username
|
||||
ko_fi: EnderIce2 # Replace with a single Ko-fi username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
|
||||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
|
392
.github/workflows/makefile.yml
vendored
392
.github/workflows/makefile.yml
vendored
@ -7,333 +7,219 @@ on:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
deploydoc:
|
||||
name: Deploy Documentation to GitHub Pages
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Doxygen
|
||||
run: sudo apt-get install doxygen make -y
|
||||
|
||||
- name: Generate Documentation
|
||||
run: make doxygen
|
||||
|
||||
- name: Copy GitHub Pages Website
|
||||
run: cp -r tools/website/* doxygen-doc/
|
||||
|
||||
- name: Deploy documentation
|
||||
uses: JamesIves/github-pages-deploy-action@v4
|
||||
with:
|
||||
folder: doxygen-doc
|
||||
|
||||
buildcompiler:
|
||||
name: Build Cross-Compiler & Toolchain
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Cache cross Folder
|
||||
id: cache-cross
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: tools/cross
|
||||
key: ${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }}
|
||||
|
||||
- name: Update System
|
||||
if: steps.cache-cross.outputs.cache-hit != 'true'
|
||||
run: sudo apt-get update
|
||||
|
||||
- name: Install GCC Dependencies
|
||||
if: steps.cache-cross.outputs.cache-hit != 'true'
|
||||
run: sudo apt install build-essential bison flex libgmp3-dev libmpc-dev libmpfr-dev texinfo libzstd-dev libisl-dev autoconf m4 automake gettext gperf dejagnu guile-3.0 guile-3.0-dev expect tcl autogen tex-common sphinx-common git ssh diffutils patch -y
|
||||
|
||||
- name: Clone All
|
||||
if: steps.cache-cross.outputs.cache-hit != 'true'
|
||||
run: make --quiet -C tools __clone_all_no_qemu
|
||||
|
||||
- name: Compile Binutils amd64
|
||||
if: steps.cache-cross.outputs.cache-hit != 'true'
|
||||
run: make --quiet -C tools do_binutils_64
|
||||
|
||||
- name: Compile Binutils i386
|
||||
if: steps.cache-cross.outputs.cache-hit != 'true'
|
||||
run: make --quiet -C tools do_binutils_32
|
||||
|
||||
- name: Compile GCC amd64
|
||||
if: steps.cache-cross.outputs.cache-hit != 'true'
|
||||
run: make --quiet -C tools do_gcc_64
|
||||
|
||||
- name: Compile GCC i386
|
||||
if: steps.cache-cross.outputs.cache-hit != 'true'
|
||||
run: make --quiet -C tools do_gcc_32
|
||||
|
||||
- name: Clean Up
|
||||
if: steps.cache-cross.outputs.cache-hit != 'true'
|
||||
- name: Prepare Environment for Dev Container
|
||||
run: |
|
||||
cd tools
|
||||
rm -rf binutils-gdb gcc build-binutils64 build-gcc64 build-binutils32 build-gcc32
|
||||
sudo mkdir -p /tmp/.X11-unix
|
||||
sudo mkdir -p /run/user/1000/pulse
|
||||
sudo touch /run/user/1000/pulse/native
|
||||
|
||||
compilegnuefi:
|
||||
name: Build GNU-EFI
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Run make ci-setup in dev container
|
||||
if: steps.cache-cross.outputs.cache-hit != 'true'
|
||||
uses: devcontainers/ci@v0.3
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Cache gnu-efi Folder
|
||||
id: cache-gnuefi
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: Lynx/gnu-efi
|
||||
key: ${{ runner.os }}-gnuefi-${{ hashFiles('Lynx/Makefile') }}
|
||||
|
||||
- name: Update System
|
||||
if: steps.cache-gnuefi.outputs.cache-hit != 'true'
|
||||
run: sudo apt-get update
|
||||
|
||||
- name: Install MinGW compiler
|
||||
if: steps.cache-gnuefi.outputs.cache-hit != 'true'
|
||||
run: sudo apt-get install make gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 -y
|
||||
|
||||
- name: Get GNU-EFI source code and compile it
|
||||
if: steps.cache-gnuefi.outputs.cache-hit != 'true'
|
||||
run: make --quiet -C Lynx prepare
|
||||
push: never
|
||||
runCmd: |
|
||||
/usr/bin/make ci-setup
|
||||
|
||||
analyze:
|
||||
name: Analyze with CodeQL
|
||||
name: Analyze (${{ matrix.language }})
|
||||
runs-on: ubuntu-latest
|
||||
needs: [buildcompiler, compilegnuefi]
|
||||
needs: [buildcompiler]
|
||||
permissions:
|
||||
security-events: write
|
||||
packages: read
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'cpp' ]
|
||||
include:
|
||||
- language: c-cpp
|
||||
build-mode: manual
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Check for cache
|
||||
id: check-cache
|
||||
run: |
|
||||
if [ -z "${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }}" ]; then
|
||||
echo "No cache found, cancelling job."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
build-mode: ${{ matrix.build-mode }}
|
||||
|
||||
- if: matrix.build-mode == 'manual'
|
||||
shell: bash
|
||||
run: |
|
||||
echo 'If you are using a "manual" build mode for one or more of the' \
|
||||
'languages you are analyzing, replace this with the commands to build' \
|
||||
'your code, for example:'
|
||||
echo ' make bootstrap'
|
||||
echo ' make release'
|
||||
exit 0
|
||||
|
||||
- name: Install Packages
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install rustc xorriso mtools genisoimage ovmf nasm doxygen make gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 build-essential bison flex libgmp3-dev libmpc-dev libmpfr-dev texinfo -y
|
||||
sudo apt update
|
||||
sudo apt --no-install-recommends -y install rustc xorriso mtools genisoimage ovmf nasm doxygen make gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 build-essential bison flex libgmp3-dev libmpc-dev libmpfr-dev texinfo
|
||||
make --quiet -C tools do_limine
|
||||
make --quiet -C Drivers prepare
|
||||
make --quiet -C Userspace prepare
|
||||
make --quiet -C Lynx prepare
|
||||
make --quiet -C Kernel prepare
|
||||
make --quiet prepare
|
||||
|
||||
- name: Cache cross
|
||||
id: cache-cross
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: tools/cross
|
||||
key: ${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }}
|
||||
|
||||
- name: Cache gnuefi
|
||||
id: cache-gnuefi
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: Lynx/gnu-efi
|
||||
key: ${{ runner.os }}-gnuefi-${{ hashFiles('Lynx/Makefile') }}
|
||||
|
||||
- name: Build OS
|
||||
run: |
|
||||
make build_lynx
|
||||
make build_userspace
|
||||
make build_drivers
|
||||
make build_kernel
|
||||
make build_userspace
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
|
||||
compile64:
|
||||
name: Build amd64
|
||||
compile:
|
||||
name: Build OS
|
||||
runs-on: ubuntu-latest
|
||||
needs: [buildcompiler, compilegnuefi]
|
||||
needs: [buildcompiler]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Update & Install Required Packages
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install rustc xorriso mtools genisoimage ovmf nasm doxygen make meson gcc-10 g++-10 gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 -y
|
||||
make --quiet -C tools do_limine
|
||||
make --quiet -C Drivers prepare
|
||||
make --quiet -C Userspace prepare
|
||||
make --quiet -C Lynx prepare
|
||||
make --quiet -C Kernel prepare
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Cache cross Folder
|
||||
id: cache-cross
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: tools/cross
|
||||
key: ${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }}
|
||||
|
||||
- name: Cache gnu-efi Folder
|
||||
id: cache-gnuefi
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: Lynx/gnu-efi
|
||||
key: ${{ runner.os }}-gnuefi-${{ hashFiles('Lynx/Makefile') }}
|
||||
|
||||
- name: Configure Makefile.conf
|
||||
run: sed -i 's/.*OSARCH = .*/OSARCH = amd64/' ./Makefile.conf && cat Makefile.conf | grep OSARCH
|
||||
|
||||
- name: Compile Debug and Release ISO
|
||||
- name: Prepare Environment for Dev Container
|
||||
run: |
|
||||
make build
|
||||
mv Fennix.iso Fennix-debug.iso
|
||||
make clean
|
||||
sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./Makefile.conf && cat Makefile.conf | grep DEBUG
|
||||
make build
|
||||
mv Fennix.iso Fennix-release.iso
|
||||
sudo mkdir -p /tmp/.X11-unix
|
||||
sudo mkdir -p /run/user/1000/pulse
|
||||
sudo touch /run/user/1000/pulse/native
|
||||
|
||||
- name: Upload Artifact (Fennix-debug.iso)
|
||||
uses: actions/upload-artifact@v3
|
||||
- name: Build AMD64 Debug
|
||||
if: always()
|
||||
uses: devcontainers/ci@v0.3
|
||||
with:
|
||||
name: Fennix-amd64-debug
|
||||
path: Fennix-debug.iso
|
||||
push: never
|
||||
runCmd: /usr/bin/make __ci-amd64-debug
|
||||
|
||||
- name: Upload Artifact (Fennix-release.iso)
|
||||
uses: actions/upload-artifact@v3
|
||||
- name: Build AMD64 Release
|
||||
if: always()
|
||||
uses: devcontainers/ci@v0.3
|
||||
with:
|
||||
name: Fennix-amd64-release
|
||||
path: Fennix-release.iso
|
||||
push: never
|
||||
runCmd: /usr/bin/make __ci-amd64-release
|
||||
|
||||
compile32:
|
||||
name: Build i386
|
||||
- name: Build i386 Debug
|
||||
if: always()
|
||||
uses: devcontainers/ci@v0.3
|
||||
with:
|
||||
push: never
|
||||
runCmd: /usr/bin/make __ci-i386-debug
|
||||
|
||||
- name: Build i386 Release
|
||||
if: always()
|
||||
uses: devcontainers/ci@v0.3
|
||||
with:
|
||||
push: never
|
||||
runCmd: /usr/bin/make __ci-i386-release
|
||||
|
||||
- name: Build ARM Debug
|
||||
if: always()
|
||||
uses: devcontainers/ci@v0.3
|
||||
with:
|
||||
push: never
|
||||
runCmd: /usr/bin/make __ci-arm-debug
|
||||
|
||||
- name: Build ARM Release
|
||||
if: always()
|
||||
uses: devcontainers/ci@v0.3
|
||||
with:
|
||||
push: never
|
||||
runCmd: /usr/bin/make __ci-arm-release
|
||||
|
||||
- name: Build AArch64 Debug
|
||||
if: always()
|
||||
uses: devcontainers/ci@v0.3
|
||||
with:
|
||||
push: never
|
||||
runCmd: /usr/bin/make __ci-aarch64-debug
|
||||
|
||||
- name: Build AArch64 Release
|
||||
if: always()
|
||||
uses: devcontainers/ci@v0.3
|
||||
with:
|
||||
push: never
|
||||
runCmd: /usr/bin/make __ci-aarch64-release
|
||||
|
||||
- name: Build Prepare Archive
|
||||
if: always()
|
||||
uses: devcontainers/ci@v0.3
|
||||
with:
|
||||
push: never
|
||||
runCmd: /usr/bin/make __ci-prepare-archive
|
||||
|
||||
- name: Upload Artifact
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: artifacts
|
||||
path: artifacts/
|
||||
|
||||
nightly:
|
||||
if: always()
|
||||
name: Upload Nightly Build to GitHub Releases
|
||||
runs-on: ubuntu-latest
|
||||
needs: [buildcompiler, compilegnuefi]
|
||||
needs: [compile]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Update & Install Required Packages
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install rustc xorriso mtools genisoimage ovmf nasm doxygen make meson gcc-10 g++-10 gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 -y
|
||||
make --quiet -C tools do_limine
|
||||
make --quiet -C Drivers prepare
|
||||
make --quiet -C Userspace prepare
|
||||
make --quiet -C Lynx prepare
|
||||
make --quiet -C Kernel prepare
|
||||
- name: Download All Builds
|
||||
uses: actions/download-artifact@v4
|
||||
|
||||
- name: Cache cross Folder
|
||||
id: cache-cross
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: tools/cross
|
||||
key: ${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }}
|
||||
- name: Update Nightly
|
||||
run: gh release upload nightly artifacts/* -R ${{github.repository}} --clobber
|
||||
|
||||
- name: Cache gnu-efi Folder
|
||||
id: cache-gnuefi
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: Lynx/gnu-efi
|
||||
key: ${{ runner.os }}-gnuefi-${{ hashFiles('Lynx/Makefile') }}
|
||||
|
||||
- name: Configure Makefile.conf
|
||||
run: sed -i 's/.*OSARCH = .*/OSARCH = i386/' ./Makefile.conf && cat Makefile.conf | grep OSARCH
|
||||
|
||||
- name: Compile Debug and Release ISO
|
||||
run: |
|
||||
make build
|
||||
mv Fennix.iso Fennix-debug.iso
|
||||
make clean
|
||||
sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./Makefile.conf && cat Makefile.conf | grep DEBUG
|
||||
make build
|
||||
mv Fennix.iso Fennix-release.iso
|
||||
|
||||
- name: Upload Artifact (Fennix-debug.iso)
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Fennix-i386-debug
|
||||
path: Fennix-debug.iso
|
||||
|
||||
- name: Upload Artifact (Fennix-release.iso)
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Fennix-i386-release
|
||||
path: Fennix-release.iso
|
||||
|
||||
compilearm64:
|
||||
if: ${{ false }} # Disabled until we can get it to work
|
||||
name: Build aarch64
|
||||
runs-on: ubuntu-latest
|
||||
needs: [buildcompiler, compilegnuefi]
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Update & Install Required Packages
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install rustc xorriso mtools genisoimage ovmf nasm doxygen make meson gcc-10 g++-10 gcc-mingw-w64-x86-64 gcc-mingw-w64-i686 mingw-w64 -y
|
||||
make --quiet -C tools do_limine
|
||||
make --quiet -C Drivers prepare
|
||||
make --quiet -C Userspace prepare
|
||||
make --quiet -C Lynx prepare
|
||||
make --quiet -C Kernel prepare
|
||||
|
||||
- name: Cache cross Folder
|
||||
id: cache-cross
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: tools/cross
|
||||
key: ${{ runner.os }}-cross-${{ hashFiles('tools/Makefile') }}
|
||||
|
||||
- name: Cache gnu-efi Folder
|
||||
id: cache-gnuefi
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: Lynx/gnu-efi
|
||||
key: ${{ runner.os }}-gnuefi-${{ hashFiles('Lynx/Makefile') }}
|
||||
|
||||
- name: Configure Makefile.conf
|
||||
run: sed -i 's/.*OSARCH = .*/OSARCH = aarch64/' ./Makefile.conf && cat Makefile.conf | grep OSARCH
|
||||
|
||||
- name: Compile Debug and Release ISO
|
||||
run: |
|
||||
make build
|
||||
mv Fennix.iso Fennix-debug.iso
|
||||
make clean
|
||||
sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./Makefile.conf && cat Makefile.conf | grep DEBUG
|
||||
make build
|
||||
mv Fennix.iso Fennix-release.iso
|
||||
|
||||
- name: Upload Artifact (Fennix-debug.iso)
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Fennix-aarch64-debug
|
||||
path: Fennix-debug.iso
|
||||
|
||||
- name: Upload Artifact (Fennix-release.iso)
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Fennix-aarch64-release
|
||||
path: Fennix-release.iso
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
|
33
.github/workflows/website.yml
vendored
Normal file
33
.github/workflows/website.yml
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
name: Deploy Website
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
paths:
|
||||
- tools/website/**
|
||||
- Kernel/include/interface/**
|
||||
- Doxyfile
|
||||
|
||||
jobs:
|
||||
deploydoc:
|
||||
name: Deploy Website to GitHub Pages
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code 🛎️
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Doxygen 📦
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt --no-install-recommends -y install doxygen make
|
||||
|
||||
- name: Generate Documentation 📚
|
||||
run: make doxygen
|
||||
|
||||
- name: Copy GitHub Pages Website 📁
|
||||
run: cp -r tools/website/* doxygen-doc/
|
||||
|
||||
- name: Deploy documentation 🚀
|
||||
uses: JamesIves/github-pages-deploy-action@v4
|
||||
with:
|
||||
folder: doxygen-doc
|
22
.gitignore
vendored
22
.gitignore
vendored
@ -1,21 +1,10 @@
|
||||
iso_tmp_data
|
||||
initrd_tmp_data
|
||||
initrd/usr/include/*
|
||||
!initrd/usr/include/.gitkeep
|
||||
tools/*
|
||||
!tools/ExtMemDbg
|
||||
!tools/stage2_eltorito
|
||||
!tools/*.md
|
||||
!tools/*.css
|
||||
!tools/README.md
|
||||
!tools/website
|
||||
!tools/Makefile
|
||||
!tools/*.c
|
||||
!tools/*.cpp
|
||||
!tools/*.cfg
|
||||
!tools/SSDT1.dat
|
||||
artifacts
|
||||
tmp_rootfs
|
||||
rootfs/usr/include/*
|
||||
!rootfs/usr/include/.gitkeep
|
||||
doxygen-doc
|
||||
initrd.tar
|
||||
rootfs.tar.gz
|
||||
.dccache
|
||||
*.log
|
||||
*.log.*
|
||||
@ -28,3 +17,4 @@ initrd.tar
|
||||
*.so
|
||||
*.o
|
||||
*.dmp
|
||||
*.pcap
|
||||
|
@ -87,11 +87,11 @@ build64:
|
||||
- make --quiet -C Userspace prepare
|
||||
- make --quiet -C Lynx prepare
|
||||
- make --quiet -C Kernel prepare
|
||||
- sed -i 's/.*OSARCH = .*/OSARCH = amd64/' ./Makefile.conf && cat Makefile.conf | grep OSARCH
|
||||
- sed -i 's/.*OSARCH = .*/OSARCH = amd64/' ./config.mk && cat config.mk | grep OSARCH
|
||||
- make build
|
||||
- mv Fennix.iso Fennix-debug.iso
|
||||
- make clean
|
||||
- sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./Makefile.conf && cat Makefile.conf | grep DEBUG
|
||||
- sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./config.mk && cat config.mk | grep DEBUG
|
||||
- make build
|
||||
- mv Fennix.iso Fennix-release.iso
|
||||
artifacts:
|
||||
@ -111,11 +111,11 @@ build32:
|
||||
- make --quiet -C Userspace prepare
|
||||
- make --quiet -C Lynx prepare
|
||||
- make --quiet -C Kernel prepare
|
||||
- sed -i 's/.*OSARCH = .*/OSARCH = i386/' ./Makefile.conf && cat Makefile.conf | grep OSARCH
|
||||
- sed -i 's/.*OSARCH = .*/OSARCH = i386/' ./config.mk && cat config.mk | grep OSARCH
|
||||
- make build
|
||||
- mv Fennix.iso Fennix-debug.iso
|
||||
- make clean
|
||||
- sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./Makefile.conf && cat Makefile.conf | grep DEBUG
|
||||
- sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./config.mk && cat config.mk | grep DEBUG
|
||||
- make build
|
||||
- mv Fennix.iso Fennix-release.iso
|
||||
artifacts:
|
||||
@ -134,11 +134,11 @@ buildarm64:
|
||||
- make --quiet -C Userspace prepare
|
||||
- make --quiet -C Lynx prepare
|
||||
- make --quiet -C Kernel prepare
|
||||
- sed -i 's/.*OSARCH = .*/OSARCH = arm64/' ./Makefile.conf && cat Makefile.conf | grep OSARCH
|
||||
- sed -i 's/.*OSARCH = .*/OSARCH = arm64/' ./config.mk && cat config.mk | grep OSARCH
|
||||
- make build
|
||||
- mv Fennix.iso Fennix-debug.iso
|
||||
- make clean
|
||||
- sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./Makefile.conf && cat Makefile.conf | grep DEBUG
|
||||
- sed -i 's/.*DEBUG = .*/DEBUG = 0/' ./config.mk && cat config.mk | grep DEBUG
|
||||
- make build
|
||||
- mv Fennix.iso Fennix-release.iso
|
||||
artifacts:
|
||||
|
20
.vscode/c_boilerplates.code-snippets
vendored
20
.vscode/c_boilerplates.code-snippets
vendored
@ -1,20 +0,0 @@
|
||||
{
|
||||
"Fennix Kernel Header": {
|
||||
"scope": "c",
|
||||
"prefix": [
|
||||
"head",
|
||||
],
|
||||
"body": [
|
||||
"#ifndef __FENNIX_KERNEL_${2:header}_H__",
|
||||
"#define __FENNIX_KERNEL_${2:header}_H__",
|
||||
"",
|
||||
"#include <types.h>",
|
||||
"",
|
||||
"$0",
|
||||
"",
|
||||
"#endif // !__FENNIX_KERNEL_${2:header}_H__",
|
||||
""
|
||||
],
|
||||
"description": "Create kernel header."
|
||||
}
|
||||
}
|
155
.vscode/launch.json
vendored
Normal file
155
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,155 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Debug Kernel (x64)",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/../Kernel/fennix.elf",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"targetArchitecture": "x64",
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerServerAddress": "/tmp/gdb-fennix",
|
||||
"miDebuggerPath": "${workspaceFolder}/../tools/cross/bin/x86_64-fennix-gdb",
|
||||
"externalConsole": false,
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"setupCommands": [
|
||||
{
|
||||
"text": "set breakpoint pending on",
|
||||
"description": "Make breakpoint pending on future shared library load."
|
||||
},
|
||||
{
|
||||
"text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/utest",
|
||||
"description": "/bin/utest (0x00400000)",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/libc_test",
|
||||
"description": "/bin/libc_test (0x00600000)",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"text": "source ${workspaceFolder}/../tools/.gdbinit"
|
||||
}
|
||||
],
|
||||
"preLaunchTask": "QEMU"
|
||||
},
|
||||
{
|
||||
"name": "Debug Kernel (x86)",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/../Kernel/fennix.elf",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"targetArchitecture": "x86",
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerServerAddress": "/tmp/gdb-fennix",
|
||||
"miDebuggerPath": "${workspaceFolder}/../tools/cross/bin/i386-fennix-gdb",
|
||||
"externalConsole": false,
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"setupCommands": [
|
||||
{
|
||||
"text": "set breakpoint pending on",
|
||||
"description": "Make breakpoint pending on future shared library load."
|
||||
},
|
||||
{
|
||||
"text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/utest",
|
||||
"description": "/bin/utest (0x00400000)",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/libc_test",
|
||||
"description": "/bin/libc_test (0x00600000)",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"text": "source ${workspaceFolder}/../tools/.gdbinit"
|
||||
}
|
||||
],
|
||||
"preLaunchTask": "QEMU"
|
||||
},
|
||||
{
|
||||
"name": "Debug Kernel (arm64)",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/../Kernel/fennix.elf",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"targetArchitecture": "arm64",
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerServerAddress": "/tmp/gdb-fennix",
|
||||
"miDebuggerPath": "${workspaceFolder}/../tools/cross/bin/aarch64-fennix-gdb",
|
||||
"externalConsole": false,
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"setupCommands": [
|
||||
{
|
||||
"text": "set breakpoint pending on",
|
||||
"description": "Make breakpoint pending on future shared library load."
|
||||
},
|
||||
{
|
||||
"text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/utest",
|
||||
"description": "/bin/utest (0x00400000)",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/libc_test",
|
||||
"description": "/bin/libc_test (0x00600000)",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"text": "source ${workspaceFolder}/../tools/.gdbinit"
|
||||
}
|
||||
],
|
||||
"preLaunchTask": "QEMU"
|
||||
},
|
||||
{
|
||||
"name": "Debug Kernel (arm)",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/../Kernel/fennix.elf",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"targetArchitecture": "arm",
|
||||
"MIMode": "gdb",
|
||||
"miDebuggerServerAddress": "/tmp/gdb-fennix",
|
||||
"miDebuggerPath": "${workspaceFolder}/../tools/cross/bin/arm-fennix-gdb",
|
||||
"externalConsole": false,
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"setupCommands": [
|
||||
{
|
||||
"text": "set breakpoint pending on",
|
||||
"description": "Make breakpoint pending on future shared library load."
|
||||
},
|
||||
{
|
||||
"text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/utest",
|
||||
"description": "/bin/utest (0x00400000)",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"text": "add-symbol-file ${workspaceFolder}/../tmp_rootfs/bin/libc_test",
|
||||
"description": "/bin/libc_test (0x00600000)",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"text": "source ${workspaceFolder}/../tools/.gdbinit"
|
||||
}
|
||||
],
|
||||
"preLaunchTask": "QEMU"
|
||||
},
|
||||
{
|
||||
"type": "gdb",
|
||||
"request": "attach",
|
||||
"name": "Launch QEMU & attach to gdbserver (x64)",
|
||||
"executable": "${workspaceFolder}/../Kernel/fennix.elf",
|
||||
"target": "/tmp/gdb-fennix",
|
||||
"remote": true,
|
||||
"cwd": "${workspaceRoot}",
|
||||
"valuesFormatting": "parseText",
|
||||
"gdbpath": "${workspaceFolder}/../tools/cross/bin/x86_64-fennix-gdb",
|
||||
"autorun": [
|
||||
"set auto-load safe-path ${workspaceFolder}",
|
||||
"source ${workspaceFolder}/../tools/.gdbinit",
|
||||
],
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"printCalls": false,
|
||||
"preLaunchTask": "QEMU"
|
||||
},
|
||||
]
|
||||
}
|
15
.vscode/settings.json
vendored
15
.vscode/settings.json
vendored
@ -1,5 +1,5 @@
|
||||
{
|
||||
"C_Cpp.errorSquiggles": "Enabled",
|
||||
"C_Cpp.errorSquiggles": "enabled",
|
||||
"C_Cpp.autocompleteAddParentheses": true,
|
||||
"C_Cpp.codeAnalysis.clangTidy.enabled": true,
|
||||
"C_Cpp.clang_format_style": "Visual Studio",
|
||||
@ -11,16 +11,11 @@
|
||||
"editor.cursorSmoothCaretAnimation": "on",
|
||||
"files.watcherExclude": {
|
||||
"**/tools/binutils-gdb/**": true,
|
||||
"**/tools/build-binutilsamd64/**": true,
|
||||
"**/tools/build-binutilsarm64/**": true,
|
||||
"**/tools/build-binutilsi386/**": true,
|
||||
"**/tools/build-gccamd64/**": true,
|
||||
"**/tools/build-gccarm64/**": true,
|
||||
"**/tools/build-gcci386/**": true,
|
||||
"**/tools/cross/**": true,
|
||||
"**/tools/gcc/**": true,
|
||||
"**/tools/limine/**": true,
|
||||
"**/tools/qemu/**": true,
|
||||
"**/tools/cross/**": true,
|
||||
"**/doxygen-doc/**": true,
|
||||
}
|
||||
}
|
||||
},
|
||||
"cmake.ignoreCMakeListsMissing": true
|
||||
}
|
||||
|
498
.vscode/tasks.json
vendored
Normal file
498
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,498 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "Clean",
|
||||
"type": "shell",
|
||||
"command": "make clean",
|
||||
"isBackground": false,
|
||||
"hide": false,
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": false
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "never",
|
||||
"panel": "shared"
|
||||
},
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/../",
|
||||
"shell": {
|
||||
"executable": "bash",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Build",
|
||||
"type": "shell",
|
||||
"command": "make build",
|
||||
"isBackground": false,
|
||||
"hide": false,
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": false
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
},
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/../",
|
||||
"shell": {
|
||||
"executable": "bash",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Run",
|
||||
"type": "shell",
|
||||
"command": "make qemu",
|
||||
"isBackground": false,
|
||||
"hide": false,
|
||||
"dependsOn": [
|
||||
"Build"
|
||||
],
|
||||
"group": {
|
||||
"kind": "test",
|
||||
"isDefault": true
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
},
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/../",
|
||||
"shell": {
|
||||
"executable": "bash",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Build Bootloader",
|
||||
"type": "shell",
|
||||
"command": "make -C ../ build_bootloader",
|
||||
"isBackground": false,
|
||||
"hide": true,
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": false
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
},
|
||||
"options": {
|
||||
"shell": {
|
||||
"executable": "bash",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Build Kernel",
|
||||
"type": "shell",
|
||||
"command": "make -C ../ build_kernel",
|
||||
"isBackground": false,
|
||||
"hide": true,
|
||||
"dependsOn": [
|
||||
"Build Bootloader"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": false
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
},
|
||||
"options": {
|
||||
"shell": {
|
||||
"executable": "bash",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Build Drivers",
|
||||
"type": "shell",
|
||||
"command": "make -C ../ build_drivers",
|
||||
"isBackground": false,
|
||||
"hide": true,
|
||||
"dependsOn": [
|
||||
"Build Kernel"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": false
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
},
|
||||
"options": {
|
||||
"shell": {
|
||||
"executable": "bash",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Build Userspace",
|
||||
"type": "shell",
|
||||
"command": "make -C ../ build_userspace",
|
||||
"isBackground": false,
|
||||
"hide": true,
|
||||
"dependsOn": [
|
||||
"Build Drivers"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": false
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
},
|
||||
"options": {
|
||||
"shell": {
|
||||
"executable": "bash",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Build Image",
|
||||
"type": "shell",
|
||||
"command": "make -C ../ build_image",
|
||||
"isBackground": false,
|
||||
"hide": true,
|
||||
"dependsOn": [
|
||||
"Build Userspace"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": false
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
},
|
||||
"options": {
|
||||
"shell": {
|
||||
"executable": "bash",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "QEMU",
|
||||
"type": "shell",
|
||||
"command": "make",
|
||||
"args": [
|
||||
"-C",
|
||||
"../",
|
||||
"vscode_debug_only"
|
||||
],
|
||||
"isBackground": true,
|
||||
// "problemMatcher": "$tsc-watch",
|
||||
"problemMatcher": [
|
||||
{
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": ".",
|
||||
"file": 1,
|
||||
"location": 2,
|
||||
"message": 3
|
||||
}
|
||||
],
|
||||
"background": {
|
||||
"activeOnStart": true,
|
||||
"beginsPattern": ".",
|
||||
"endsPattern": "CPU Reset",
|
||||
}
|
||||
}
|
||||
],
|
||||
"dependsOn": [
|
||||
"Build Image"
|
||||
],
|
||||
"group": {
|
||||
"kind": "test",
|
||||
"isDefault": true
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
},
|
||||
"options": {
|
||||
"shell": {
|
||||
"executable": "bash",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "CI AMD64 Debug",
|
||||
"type": "shell",
|
||||
"command": "make __ci-amd64-debug",
|
||||
"isBackground": false,
|
||||
"hide": true,
|
||||
"dependsOn": [
|
||||
"Clean"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": false
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
},
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/../",
|
||||
"shell": {
|
||||
"executable": "bash",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "CI AMD64 Release",
|
||||
"type": "shell",
|
||||
"command": "make __ci-amd64-release",
|
||||
"isBackground": false,
|
||||
"hide": true,
|
||||
"dependsOn": [
|
||||
"CI AMD64 Debug"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": false
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
},
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/../",
|
||||
"shell": {
|
||||
"executable": "bash",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "CI i386 Debug",
|
||||
"type": "shell",
|
||||
"command": "make __ci-i386-debug",
|
||||
"isBackground": false,
|
||||
"hide": true,
|
||||
"dependsOn": [
|
||||
"CI AMD64 Release"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": false
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
},
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/../",
|
||||
"shell": {
|
||||
"executable": "bash",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "CI i386 Release",
|
||||
"type": "shell",
|
||||
"command": "make __ci-i386-release",
|
||||
"isBackground": false,
|
||||
"hide": true,
|
||||
"dependsOn": [
|
||||
"CI i386 Debug"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": false
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
},
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/../",
|
||||
"shell": {
|
||||
"executable": "bash",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "CI ARM Debug",
|
||||
"type": "shell",
|
||||
"command": "make __ci-arm-debug",
|
||||
"isBackground": false,
|
||||
"hide": true,
|
||||
"dependsOn": [
|
||||
"CI i386 Release"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": false
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
},
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/../",
|
||||
"shell": {
|
||||
"executable": "bash",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "CI ARM Release",
|
||||
"type": "shell",
|
||||
"command": "make __ci-arm-release",
|
||||
"isBackground": false,
|
||||
"hide": true,
|
||||
"dependsOn": [
|
||||
"CI ARM Debug"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": false
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
},
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/../",
|
||||
"shell": {
|
||||
"executable": "bash",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "CI AARCH64 Debug",
|
||||
"type": "shell",
|
||||
"command": "make __ci-aarch64-debug",
|
||||
"isBackground": false,
|
||||
"hide": true,
|
||||
"dependsOn": [
|
||||
"CI ARM Release"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": false
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
},
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/../",
|
||||
"shell": {
|
||||
"executable": "bash",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "CI AARCH64 Release",
|
||||
"type": "shell",
|
||||
"command": "make __ci-aarch64-release",
|
||||
"isBackground": false,
|
||||
"hide": true,
|
||||
"dependsOn": [
|
||||
"CI AARCH64 Debug"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": false
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
},
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/../",
|
||||
"shell": {
|
||||
"executable": "bash",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Test CI Build",
|
||||
"type": "shell",
|
||||
"command": "make __ci-restore-config",
|
||||
"isBackground": false,
|
||||
"dependsOn": [
|
||||
"CI AARCH64 Release",
|
||||
"clean"
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": false
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "shared"
|
||||
},
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/../",
|
||||
"shell": {
|
||||
"executable": "bash",
|
||||
"args": [
|
||||
"-c"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
13
Bootloader/.editorconfig
Normal file
13
Bootloader/.editorconfig
Normal file
@ -0,0 +1,13 @@
|
||||
# EditorConfig is awesome: https://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
10
Bootloader/.gitignore
vendored
Normal file
10
Bootloader/.gitignore
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
gnu-efi
|
||||
include/*
|
||||
!include/stdbool.h
|
||||
!include/types.h
|
||||
*.o
|
||||
*.su
|
||||
*.EFI
|
||||
*.map
|
||||
*.bin
|
||||
*.elf
|
96
Bootloader/.vscode/c_boilerplates.code-snippets
vendored
Normal file
96
Bootloader/.vscode/c_boilerplates.code-snippets
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
{
|
||||
"Lynx Bootloader C++ Header": {
|
||||
"isFileTemplate": true,
|
||||
"scope": "c,cpp",
|
||||
"prefix": [
|
||||
"head",
|
||||
],
|
||||
"body": [
|
||||
"/*",
|
||||
"\tThis file is part of Lynx Bootloader.",
|
||||
"",
|
||||
"\tLynx Bootloader is free software: you can redistribute it and/or",
|
||||
"\tmodify it under the terms of the GNU General Public License as",
|
||||
"\tpublished by the Free Software Foundation, either version 3 of",
|
||||
"\tthe License, or (at your option) any later version.",
|
||||
"",
|
||||
"\tLynx Bootloader is distributed in the hope that it will be useful,",
|
||||
"\tbut WITHOUT ANY WARRANTY; without even the implied warranty of",
|
||||
"\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
|
||||
"\tGNU General Public License for more details.",
|
||||
"",
|
||||
"\tYou should have received a copy of the GNU General Public License",
|
||||
"\talong with Lynx Bootloader. If not, see <https://www.gnu.org/licenses/>.",
|
||||
"*/",
|
||||
"",
|
||||
"#pragma once",
|
||||
"",
|
||||
"$0",
|
||||
"",
|
||||
"$1",
|
||||
""
|
||||
],
|
||||
"description": "Create kernel header."
|
||||
},
|
||||
"Lynx Bootloader C Header": {
|
||||
"isFileTemplate": true,
|
||||
"scope": "c,cpp",
|
||||
"prefix": [
|
||||
"headc",
|
||||
],
|
||||
"body": [
|
||||
"/*",
|
||||
"\tThis file is part of Lynx Bootloader.",
|
||||
"",
|
||||
"\tLynx Bootloader is free software: you can redistribute it and/or",
|
||||
"\tmodify it under the terms of the GNU General Public License as",
|
||||
"\tpublished by the Free Software Foundation, either version 3 of",
|
||||
"\tthe License, or (at your option) any later version.",
|
||||
"",
|
||||
"\tLynx Bootloader is distributed in the hope that it will be useful,",
|
||||
"\tbut WITHOUT ANY WARRANTY; without even the implied warranty of",
|
||||
"\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
|
||||
"\tGNU General Public License for more details.",
|
||||
"",
|
||||
"\tYou should have received a copy of the GNU General Public License",
|
||||
"\talong with Lynx Bootloader. If not, see <https://www.gnu.org/licenses/>.",
|
||||
"*/",
|
||||
"",
|
||||
"#ifndef __LYNX_BOOTLOADER_${1:header}_H__",
|
||||
"#define __LYNX_BOOTLOADER_${1:header}_H__",
|
||||
"",
|
||||
"#include <types.h>",
|
||||
"",
|
||||
"$0",
|
||||
"",
|
||||
"#endif // !__LYNX_BOOTLOADER_${1:header}_H__",
|
||||
""
|
||||
],
|
||||
"description": "Create kernel header."
|
||||
},
|
||||
"License": {
|
||||
"isFileTemplate": true,
|
||||
"prefix": [
|
||||
"license",
|
||||
],
|
||||
"body": [
|
||||
"/*",
|
||||
"\tThis file is part of Lynx Bootloader.",
|
||||
"",
|
||||
"\tLynx Bootloader is free software: you can redistribute it and/or",
|
||||
"\tmodify it under the terms of the GNU General Public License as",
|
||||
"\tpublished by the Free Software Foundation, either version 3 of",
|
||||
"\tthe License, or (at your option) any later version.",
|
||||
"",
|
||||
"\tLynx Bootloader is distributed in the hope that it will be useful,",
|
||||
"\tbut WITHOUT ANY WARRANTY; without even the implied warranty of",
|
||||
"\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the",
|
||||
"\tGNU General Public License for more details.",
|
||||
"",
|
||||
"\tYou should have received a copy of the GNU General Public License",
|
||||
"\talong with Lynx Bootloader. If not, see <https://www.gnu.org/licenses/>.",
|
||||
"*/"
|
||||
],
|
||||
"description": "Create kernel license."
|
||||
}
|
||||
}
|
184
Bootloader/.vscode/c_cpp_properties.json
vendored
Normal file
184
Bootloader/.vscode/c_cpp_properties.json
vendored
Normal file
@ -0,0 +1,184 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Fennix x64 (Linux, GCC, debug)",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/include",
|
||||
"${workspaceFolder}/include/**"
|
||||
],
|
||||
"defines": [
|
||||
"DEBUG=\"1\""
|
||||
],
|
||||
"forcedInclude": [
|
||||
"${workspaceFolder}/.vscode/preinclude.h"
|
||||
],
|
||||
"compilerPath": "${workspaceFolder}/../tools/cross/bin/x86_64-fennix-gcc",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++20",
|
||||
"intelliSenseMode": "gcc-x64",
|
||||
"configurationProvider": "ms-vscode.makefile-tools",
|
||||
"compilerArgs": [
|
||||
// Compiler flags
|
||||
"-fno-pic",
|
||||
"-fno-pie",
|
||||
"-mno-red-zone",
|
||||
"-march=core2",
|
||||
"-pipe",
|
||||
"-mcmodel=kernel",
|
||||
"-fno-builtin",
|
||||
"-m64",
|
||||
"-fcoroutines",
|
||||
// Warnings
|
||||
"-Wall",
|
||||
"-Wextra",
|
||||
"-Wfloat-equal",
|
||||
"-Wpointer-arith",
|
||||
"-Wcast-align",
|
||||
"-Wredundant-decls",
|
||||
"-Winit-self",
|
||||
"-Wswitch-default",
|
||||
"-Wstrict-overflow=5",
|
||||
"-Wconversion",
|
||||
// C++ flags
|
||||
"-fno-rtti",
|
||||
"-fno-exceptions",
|
||||
// Linker flags
|
||||
"-T${workspaceFolder}/arch/amd64/linker.ld",
|
||||
"-Wl,-static,--no-dynamic-linker,-ztext",
|
||||
"-nostdlib",
|
||||
"-nodefaultlibs",
|
||||
"-nolibc",
|
||||
"-zmax-page-size=0x1000",
|
||||
"-shared",
|
||||
// Debug flags
|
||||
"-ggdb3",
|
||||
"-O0",
|
||||
"-fdiagnostics-color=always",
|
||||
"-fverbose-asm",
|
||||
"-fstack-usage",
|
||||
"-fstack-check",
|
||||
"-fsanitize=undefined",
|
||||
// VSCode flags
|
||||
"-ffreestanding",
|
||||
"-nostdinc",
|
||||
"-nostdinc++"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Fennix x32 (Linux, GCC, debug)",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/include",
|
||||
"${workspaceFolder}/include/**"
|
||||
],
|
||||
"forcedInclude": [
|
||||
"${workspaceFolder}/.vscode/preinclude.h"
|
||||
],
|
||||
"defines": [
|
||||
"DEBUG=\"1\""
|
||||
],
|
||||
"compilerPath": "${workspaceFolder}/../tools/cross/bin/i386-fennix-gcc",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++20",
|
||||
"intelliSenseMode": "gcc-x86",
|
||||
"configurationProvider": "ms-vscode.makefile-tools",
|
||||
"compilerArgs": [
|
||||
// Compiler flags
|
||||
"-fno-pic",
|
||||
"-fno-pie",
|
||||
"-mno-80387",
|
||||
"-mno-mmx",
|
||||
"-mno-3dnow",
|
||||
"-mno-red-zone",
|
||||
"-march=pentium",
|
||||
"-pipe",
|
||||
"-msoft-float",
|
||||
"-fno-builtin",
|
||||
"-m32",
|
||||
"-fcoroutines",
|
||||
// Warnings
|
||||
"-Wall",
|
||||
"-Wextra",
|
||||
"-Wfloat-equal",
|
||||
"-Wpointer-arith",
|
||||
"-Wcast-align",
|
||||
"-Wredundant-decls",
|
||||
"-Winit-self",
|
||||
"-Wswitch-default",
|
||||
"-Wstrict-overflow=5",
|
||||
"-Wconversion",
|
||||
// C++ flags
|
||||
"-fno-rtti",
|
||||
"-fno-exceptions",
|
||||
// Linker flags
|
||||
"-T${workspaceFolder}/arch/i386/linker.ld",
|
||||
"-Wl,-static,--no-dynamic-linker,-ztext",
|
||||
"-nostdlib",
|
||||
"-nodefaultlibs",
|
||||
"-nolibc",
|
||||
"-zmax-page-size=0x1000",
|
||||
"-shared",
|
||||
// Debug flags
|
||||
"-ggdb3",
|
||||
"-O0",
|
||||
"-fdiagnostics-color=always",
|
||||
"-fverbose-asm",
|
||||
"-fstack-usage",
|
||||
"-fstack-check",
|
||||
"-fsanitize=undefined",
|
||||
// VSCode flags
|
||||
"-ffreestanding",
|
||||
"-nostdinc",
|
||||
"-nostdinc++"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Fennix Arm (Linux, GCC, debug)",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/include",
|
||||
"${workspaceFolder}/include/**"
|
||||
],
|
||||
"forcedInclude": [
|
||||
"${workspaceFolder}/.vscode/preinclude.h"
|
||||
],
|
||||
"defines": [
|
||||
"DEBUG=\"1\""
|
||||
],
|
||||
"compilerPath": "${workspaceFolder}/../tools/cross/bin/arm-fennix-gcc",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++20",
|
||||
"intelliSenseMode": "linux-gcc-arm",
|
||||
"configurationProvider": "ms-vscode.makefile-tools",
|
||||
"compilerArgs": [
|
||||
// VSCode flags
|
||||
"-ffreestanding",
|
||||
"-nostdinc",
|
||||
"-nostdinc++"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Fennix Aarch64 (Linux, GCC, debug)",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/include",
|
||||
"${workspaceFolder}/include/**"
|
||||
],
|
||||
"forcedInclude": [
|
||||
"${workspaceFolder}/.vscode/preinclude.h"
|
||||
],
|
||||
"defines": [
|
||||
"DEBUG=\"1\""
|
||||
],
|
||||
"compilerPath": "${workspaceFolder}/../tools/cross/bin/aarch64-fennix-gcc",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++20",
|
||||
"intelliSenseMode": "linux-gcc-arm64",
|
||||
"configurationProvider": "ms-vscode.makefile-tools",
|
||||
"compilerArgs": [
|
||||
// VSCode flags
|
||||
"-ffreestanding",
|
||||
"-nostdinc",
|
||||
"-nostdinc++"
|
||||
]
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
1
Bootloader/.vscode/launch.json
vendored
Symbolic link
1
Bootloader/.vscode/launch.json
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../../.vscode/launch.json
|
11
Bootloader/.vscode/preinclude.h
vendored
Normal file
11
Bootloader/.vscode/preinclude.h
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
#undef __linux__
|
||||
#undef __WIN32__
|
||||
#undef __WIN64__
|
||||
#undef _WIN32
|
||||
#undef _WIN64
|
||||
#undef __APPLE__
|
||||
#undef __clang__
|
||||
#define __vscode__ 1
|
||||
#define __kernel__ 1
|
||||
#define GIT_COMMIT "0000000000000000000000000000000000000000"
|
||||
#define GIT_COMMIT_SHORT "0000000"
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"C_Cpp.errorSquiggles": "Enabled",
|
||||
"C_Cpp.errorSquiggles": "enabled",
|
||||
"C_Cpp.autocompleteAddParentheses": true,
|
||||
"C_Cpp.codeAnalysis.clangTidy.enabled": true,
|
||||
"C_Cpp.clang_format_style": "Visual Studio",
|
||||
@ -14,6 +14,10 @@
|
||||
"clang-diagnostic-unknown-warning-option",
|
||||
"clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling",
|
||||
"clang-diagnostic-implicit-exception-spec-mismatch",
|
||||
"clang-diagnostic-unknown-attributes"
|
||||
"clang-diagnostic-unknown-attributes",
|
||||
"clang-diagnostic-user-defined-literals",
|
||||
"clang-diagnostic-non-pod-varargs",
|
||||
"clang-diagnostic-non-pod-varargs",
|
||||
"clang-diagnostic-non-pod-varargs"
|
||||
]
|
||||
}
|
1
Bootloader/.vscode/tasks.json
vendored
Symbolic link
1
Bootloader/.vscode/tasks.json
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../../.vscode/tasks.json
|
56
Bootloader/Makefile
Normal file
56
Bootloader/Makefile
Normal file
@ -0,0 +1,56 @@
|
||||
GNUEFI_RELEASE_VERSION=3.0.18
|
||||
|
||||
GIT_COMMIT = $(shell git rev-parse HEAD)
|
||||
GIT_COMMIT_SHORT = $(shell git rev-parse --short HEAD)
|
||||
|
||||
export CC := $(__CONF_CC)
|
||||
export CXX := $(__CONF_CXX)
|
||||
export LD := $(__CONF_LD)
|
||||
export AS := $(__CONF_AS)
|
||||
export AR := $(__CONF_AR)
|
||||
export NM := $(__CONF_NM)
|
||||
export OBJCOPY := $(__CONF_OBJCOPY)
|
||||
export OBJDUMP := $(__CONF_OBJDUMP)
|
||||
export GDB := $(__CONF_GDB)
|
||||
|
||||
default:
|
||||
$(error Do not run this Makefile directly!)
|
||||
|
||||
prepare:
|
||||
ifeq ("$(wildcard ./gnu-efi)", "")
|
||||
wget https://freefr.dl.sourceforge.net/project/gnu-efi/gnu-efi-$(GNUEFI_RELEASE_VERSION).tar.bz2
|
||||
tar -xf gnu-efi-$(GNUEFI_RELEASE_VERSION).tar.bz2
|
||||
rm gnu-efi-$(GNUEFI_RELEASE_VERSION).tar.bz2
|
||||
mv ./gnu-efi-$(GNUEFI_RELEASE_VERSION) ./gnu-efi
|
||||
cp -a ./gnu-efi/inc/. ./include
|
||||
endif
|
||||
# echo "PREPARE > Compiling gnu-efi for x86_64"
|
||||
# make -C gnu-efi all ARCH=x86_64 \
|
||||
# AR=$(TOOLCHAIN_AMD64_PREFIX)ar \
|
||||
# AS=$(TOOLCHAIN_AMD64_PREFIX)as \
|
||||
# CC=$(TOOLCHAIN_AMD64_PREFIX)gcc \
|
||||
# LD=$(TOOLCHAIN_AMD64_PREFIX)ld
|
||||
# echo "PREPARE > Compiling gnu-efi for arm"
|
||||
# make -C gnu-efi all ARCH=arm \
|
||||
# AR=$(TOOLCHAIN_ARM_PREFIX)ar \
|
||||
# AS=$(TOOLCHAIN_ARM_PREFIX)as \
|
||||
# CC=$(TOOLCHAIN_ARM_PREFIX)gcc \
|
||||
# LD=$(TOOLCHAIN_ARM_PREFIX)ld \
|
||||
# CFLAGS="-I$(CURDIR)/gnu-efi/inc"
|
||||
# echo "PREPARE > Compiling gnu-efi for aarch64"
|
||||
# make -C gnu-efi all ARCH=aarch64 \
|
||||
# AR=$(TOOLCHAIN_AARCH64_PREFIX)ar \
|
||||
# AS=$(TOOLCHAIN_AARCH64_PREFIX)as \
|
||||
# CC=$(TOOLCHAIN_AARCH64_PREFIX)gcc \
|
||||
# LD=$(TOOLCHAIN_AARCH64_PREFIX)ld
|
||||
|
||||
build:
|
||||
$(MAKE) -C common build
|
||||
$(MAKE) -C firmware build
|
||||
# $(MAKE) -C uefi build
|
||||
|
||||
clean:
|
||||
$(MAKE) -C common clean
|
||||
$(MAKE) -C firmware clean
|
||||
# $(MAKE) -C uefi clean
|
||||
rm -f boot.bin
|
13
Bootloader/README.md
Normal file
13
Bootloader/README.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Lynx Bootloader
|
||||
|
||||
> [!CAUTION]
|
||||
> The project is in early stages of development and is not yet ready for production use.
|
||||
>
|
||||
> Use at your own risk.
|
||||
|
||||
|
||||
## Introduction
|
||||
|
||||
### [bios](bios)
|
||||
|
||||
### [uefi](uefi)
|
19
Bootloader/common/Makefile
Normal file
19
Bootloader/common/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
define find-sources
|
||||
$(shell find ./ -type f -name '$1' -print0 | xargs -0)
|
||||
endef
|
||||
|
||||
BMP_SOURCES := $(call find-sources,*.bmp)
|
||||
PSF_SOURCES := $(call find-sources,*.psf)
|
||||
S_SOURCES := $(call find-sources,*.S)
|
||||
s_SOURCES := $(call find-sources,*.s)
|
||||
C_SOURCES := $(call find-sources,*.c)
|
||||
CXX_SOURCES := $(call find-sources,*.cpp)
|
||||
|
||||
OBJ = $(BMP_SOURCES:.bmp=.o) $(PSF_SOURCES:.psf=.o) $(s_SOURCES:.s=.o) $(S_SOURCES:.S=.o) $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o)
|
||||
|
||||
default:
|
||||
$(error Do not run this Makefile directly!)
|
||||
|
||||
build:
|
||||
|
||||
clean:
|
21
Bootloader/common/main.c
Normal file
21
Bootloader/common/main.c
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
This file is part of Lynx Bootloader.
|
||||
|
||||
Lynx Bootloader is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Lynx Bootloader is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Lynx Bootloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
8
Bootloader/firmware/Makefile
Normal file
8
Bootloader/firmware/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
default:
|
||||
$(error Do not run this Makefile directly!)
|
||||
|
||||
build:
|
||||
$(MAKE) -C $(OSARCH) build
|
||||
|
||||
clean:
|
||||
$(MAKE) -C $(OSARCH) clean
|
64
Bootloader/firmware/aarch64/Makefile
Normal file
64
Bootloader/firmware/aarch64/Makefile
Normal file
@ -0,0 +1,64 @@
|
||||
define find-sources
|
||||
$(shell find ./ -type f -name '$1' $(shell echo $(foreach board,$(filter-out $(BOARD_TYPE),$(AVAILABLE_BOARDS)), -not -path \"./$(board)/*\")) -print0 | xargs -0)
|
||||
endef
|
||||
|
||||
S_SOURCES := $(call find-sources,*.S)
|
||||
s_SOURCES := $(call find-sources,*.s)
|
||||
C_SOURCES := $(call find-sources,*.c)
|
||||
|
||||
define find-common-sources
|
||||
$(shell find ../../common -type f -name '$1' -print0 | xargs -0)
|
||||
endef
|
||||
|
||||
C_COMMON_SOURCES := $(call find-common-sources,*.c)
|
||||
|
||||
OBJ = $(s_SOURCES:.s=.o) $(S_SOURCES:.S=.o) $(C_SOURCES:.c=.o) $(C_COMMON_SOURCES:.c=.o)
|
||||
|
||||
LDFLAGS = -static -nostdlib -nodefaultlibs -nolibc \
|
||||
-Wl,-static,--no-dynamic-linker,-ztext \
|
||||
-zmax-page-size=0x1000 \
|
||||
-Wl,-Map boot.map -fno-pic -fno-pie
|
||||
|
||||
CFLAGS := \
|
||||
$(INCLUDE_DIR) \
|
||||
-D__kernel__='1' \
|
||||
-DGIT_COMMIT='"$(GIT_COMMIT)"' \
|
||||
-DGIT_COMMIT_SHORT='"$(GIT_COMMIT_SHORT)"' \
|
||||
-fno-pic -fno-pie -fno-builtin -I../../include
|
||||
|
||||
CFLAGS += -mcmodel=large
|
||||
LDFLAGS += -T$(BOARD_TYPE)/linker.ld
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always
|
||||
# CFLAGS += -fsanitize=undefined
|
||||
CFLAGS += -fstack-check -fverbose-asm
|
||||
LDFLAGS += -ggdb3 -O0
|
||||
ASFLAGS += -g --gstabs+ --gdwarf-5 -D
|
||||
endif # DEBUG
|
||||
|
||||
default:
|
||||
$(error Do not run this Makefile directly!)
|
||||
|
||||
build: boot.bin
|
||||
|
||||
boot.bin: $(OBJ)
|
||||
$(info Linking $@)
|
||||
$(CC) $(LDFLAGS) $(OBJ) -o tmp.elf
|
||||
$(OBJCOPY) tmp.elf -O binary ../../boot.bin
|
||||
# rm tmp.elf
|
||||
|
||||
%.o: %.c $(HEADERS)
|
||||
$(info Compiling $<)
|
||||
$(CC) $(CFLAGS) -fstack-protector-all -std=c17 -c $< -o $@
|
||||
|
||||
%.o: %.S
|
||||
$(info Compiling $<)
|
||||
$(AS) $(ASFLAGS) -c $< -o $@
|
||||
|
||||
%.o: %.s
|
||||
$(info Compiling $<)
|
||||
$(AS) $(ASFLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJ) boot.map
|
1
Bootloader/firmware/aarch64/raspi3
Symbolic link
1
Bootloader/firmware/aarch64/raspi3
Symbolic link
@ -0,0 +1 @@
|
||||
./raspi4
|
49
Bootloader/firmware/aarch64/raspi4/boot.S
Normal file
49
Bootloader/firmware/aarch64/raspi4/boot.S
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
This file is part of Lynx Bootloader.
|
||||
|
||||
Lynx Bootloader is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Lynx Bootloader is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Lynx Bootloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.section ".text.boot"
|
||||
|
||||
.extern __bss_start
|
||||
.extern __bss_end
|
||||
.extern __bss_size
|
||||
|
||||
.global _start
|
||||
_start:
|
||||
/* Keep only the main core */
|
||||
mrs x1, mpidr_el1
|
||||
and x1, x1, #3
|
||||
cbz x1, 2f
|
||||
|
||||
/* Halt */
|
||||
1: wfe
|
||||
b 1b
|
||||
|
||||
/* Initialize the stack */
|
||||
2: ldr x1, =_start
|
||||
mov sp, x1
|
||||
|
||||
/* Clear the BSS */
|
||||
ldr x1, =__bss_start
|
||||
ldr w2, =__bss_size
|
||||
3: cbz w2, 4f
|
||||
str xzr, [x1], #8
|
||||
sub w2, w2, #1
|
||||
cbnz w2, 3b
|
||||
|
||||
/* Start the kernel */
|
||||
4: bl _aarch64_start
|
||||
b 1b
|
32
Bootloader/firmware/aarch64/raspi4/init.c
Normal file
32
Bootloader/firmware/aarch64/raspi4/init.c
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
This file is part of Lynx Bootloader.
|
||||
|
||||
Lynx Bootloader is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Lynx Bootloader is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Lynx Bootloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <types.h>
|
||||
|
||||
uintptr_t __stack_chk_guard = 0;
|
||||
|
||||
__noreturn __no_stack_protector void __stack_chk_fail(void)
|
||||
{
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
int main();
|
||||
__attribute__((section(".bootstrap.text"))) void _aarch64_start(uint64_t dtb_ptr32, uint64_t x1, uint64_t x2, uint64_t x3)
|
||||
{
|
||||
main();
|
||||
}
|
70
Bootloader/firmware/aarch64/raspi4/linker.ld
Normal file
70
Bootloader/firmware/aarch64/raspi4/linker.ld
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
This file is part of Lynx Bootloader.
|
||||
|
||||
Lynx Bootloader is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Lynx Bootloader is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Lynx Bootloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT("elf64-littleaarch64")
|
||||
OUTPUT_ARCH(aarch64)
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = 0x80000;
|
||||
__start = .;
|
||||
__text_start = .;
|
||||
.text :
|
||||
{
|
||||
KEEP(*(.text.boot))
|
||||
*(.text)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
__text_end = .;
|
||||
|
||||
__rodata_start = .;
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
__rodata_end = .;
|
||||
|
||||
__data_start = .;
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
__data_end = .;
|
||||
|
||||
__bss_start = .;
|
||||
.bss :
|
||||
{
|
||||
bss = .;
|
||||
*(.bss)
|
||||
}
|
||||
. = ALIGN(4096);
|
||||
__bss_end = .;
|
||||
__bss_size = __bss_end - __bss_start; /* SIZEOF(.bss); */
|
||||
__end = .;
|
||||
|
||||
/DISCARD/ :
|
||||
{
|
||||
*(.comment*)
|
||||
*(.gnu*)
|
||||
*(.note*)
|
||||
*(.eh_frame*)
|
||||
}
|
||||
}
|
6
Bootloader/firmware/amd64/Makefile
Normal file
6
Bootloader/firmware/amd64/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
default:
|
||||
$(error Do not run this Makefile directly!)
|
||||
|
||||
build:
|
||||
|
||||
clean:
|
6
Bootloader/firmware/arm/Makefile
Normal file
6
Bootloader/firmware/arm/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
default:
|
||||
$(error Do not run this Makefile directly!)
|
||||
|
||||
build:
|
||||
|
||||
clean:
|
6
Bootloader/firmware/i386/Makefile
Normal file
6
Bootloader/firmware/i386/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
default:
|
||||
$(error Do not run this Makefile directly!)
|
||||
|
||||
build:
|
||||
|
||||
clean:
|
26
Bootloader/include/stdbool.h
Normal file
26
Bootloader/include/stdbool.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
This file is part of Lynx Bootloader.
|
||||
|
||||
Lynx Bootloader is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Lynx Bootloader is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Lynx Bootloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __STDBOOL_H__
|
||||
#define __STDBOOL_H__
|
||||
|
||||
|
||||
typedef int bool;
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
#endif /* __STDBOOL_H__ */
|
496
Bootloader/include/types.h
Normal file
496
Bootloader/include/types.h
Normal file
@ -0,0 +1,496 @@
|
||||
/*
|
||||
This file is part of Lynx Bootloader.
|
||||
|
||||
Lynx Bootloader is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Lynx Bootloader is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Lynx Bootloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_TYPES_H__
|
||||
#define __FENNIX_KERNEL_TYPES_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* It doesn't do anything.
|
||||
*
|
||||
* Used to specify a function that is dependent on the architecture.
|
||||
* It's architecture specific variant is defined in arch/<arch>/...
|
||||
*/
|
||||
#define arch
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERNC extern "C"
|
||||
#define START_EXTERNC \
|
||||
EXTERNC \
|
||||
{
|
||||
#define END_EXTERNC \
|
||||
}
|
||||
#else // __cplusplus
|
||||
#define EXTERNC
|
||||
#define START_EXTERNC
|
||||
#define END_EXTERNC
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define NULL 0
|
||||
#else // __cplusplus
|
||||
#define NULL ((void *)0)
|
||||
#endif // __cplusplus
|
||||
|
||||
#define asm __asm__
|
||||
#define asmv __asm__ volatile
|
||||
|
||||
#define inf_loop while (1)
|
||||
#define ilp inf_loop; /* Used for debugging */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define foreach for
|
||||
#define in :
|
||||
|
||||
#define forItr(itr, container) \
|
||||
for (auto itr = container.begin(); \
|
||||
itr != container.end(); ++itr)
|
||||
|
||||
#define r_cst(t, v) reinterpret_cast<t>(v)
|
||||
#define c_cst(t, v) const_cast<t>(v)
|
||||
#define s_cst(t, v) static_cast<t>(v)
|
||||
#define d_cst(t, v) dynamic_cast<t>(v)
|
||||
#endif // __cplusplus
|
||||
|
||||
#define UNUSED(x) (void)(x)
|
||||
#define CONCAT(x, y) x##y
|
||||
|
||||
#ifndef __va_list__
|
||||
typedef __builtin_va_list va_list;
|
||||
#endif
|
||||
|
||||
#define va_start(v, l) __builtin_va_start(v, l)
|
||||
#define va_end(v) __builtin_va_end(v)
|
||||
#define va_arg(v, l) __builtin_va_arg(v, l)
|
||||
|
||||
#define ALIGN_UP(x, align) ((__typeof__(x))(((uintptr_t)(x) + ((align) - 1)) & (~((align) - 1))))
|
||||
#define ALIGN_DOWN(x, align) ((__typeof__(x))((x) & (~((align) - 1))))
|
||||
|
||||
#define offsetof(type, member) __builtin_offsetof(type, member)
|
||||
|
||||
#define RGB_TO_HEX(r, g, b) ((r << 16) | (g << 8) | (b))
|
||||
|
||||
#define MAX(a, b) \
|
||||
({ \
|
||||
__typeof__(a) _a = (a); \
|
||||
__typeof__(b) _b = (b); \
|
||||
_a > _b ? _a : _b; \
|
||||
})
|
||||
|
||||
#define MIN(a, b) \
|
||||
({ \
|
||||
__typeof__(a) _a = (a); \
|
||||
__typeof__(b) _b = (b); \
|
||||
_a < _b ? _a : _b; \
|
||||
})
|
||||
|
||||
#define ROUND_UP(x, y) (((x) + (y) - 1) & ~((y) - 1))
|
||||
#define ROUND_DOWN(x, y) ((x) & ~((y) - 1))
|
||||
|
||||
#define VPOKE(type, address) (*((volatile type *)(address)))
|
||||
#define POKE(type, address) (*((type *)(address)))
|
||||
|
||||
#ifndef __SIG_ATOMIC_TYPE__
|
||||
#define __SIG_ATOMIC_TYPE__ int
|
||||
#endif
|
||||
|
||||
typedef __INT8_TYPE__ int8_t;
|
||||
typedef __INT16_TYPE__ int16_t;
|
||||
typedef __INT32_TYPE__ int32_t;
|
||||
typedef __INT64_TYPE__ int64_t;
|
||||
|
||||
typedef __UINT8_TYPE__ uint8_t;
|
||||
typedef __UINT16_TYPE__ uint16_t;
|
||||
typedef __UINT32_TYPE__ uint32_t;
|
||||
typedef __UINT64_TYPE__ uint64_t;
|
||||
|
||||
typedef __INT_LEAST8_TYPE__ int_least8_t;
|
||||
typedef __INT_LEAST16_TYPE__ int_least16_t;
|
||||
typedef __INT_LEAST32_TYPE__ int_least32_t;
|
||||
typedef __INT_LEAST64_TYPE__ int_least64_t;
|
||||
|
||||
typedef __UINT_LEAST8_TYPE__ uint_least8_t;
|
||||
typedef __UINT_LEAST16_TYPE__ uint_least16_t;
|
||||
typedef __UINT_LEAST32_TYPE__ uint_least32_t;
|
||||
typedef __UINT_LEAST64_TYPE__ uint_least64_t;
|
||||
|
||||
typedef __INT_FAST8_TYPE__ int_fast8_t;
|
||||
typedef __INT_FAST16_TYPE__ int_fast16_t;
|
||||
typedef __INT_FAST32_TYPE__ int_fast32_t;
|
||||
typedef __INT_FAST64_TYPE__ int_fast64_t;
|
||||
|
||||
typedef __UINT_FAST8_TYPE__ uint_fast8_t;
|
||||
typedef __UINT_FAST16_TYPE__ uint_fast16_t;
|
||||
typedef __UINT_FAST32_TYPE__ uint_fast32_t;
|
||||
typedef __UINT_FAST64_TYPE__ uint_fast64_t;
|
||||
|
||||
typedef __INTPTR_TYPE__ intptr_t;
|
||||
typedef __UINTPTR_TYPE__ uintptr_t;
|
||||
|
||||
typedef __INTMAX_TYPE__ intmax_t;
|
||||
typedef __UINTMAX_TYPE__ uintmax_t;
|
||||
|
||||
typedef __PTRDIFF_TYPE__ ptrdiff_t;
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
#ifndef __cplusplus
|
||||
typedef __WCHAR_TYPE__ wchar_t;
|
||||
#endif
|
||||
typedef __WINT_TYPE__ wint_t;
|
||||
typedef __SIG_ATOMIC_TYPE__ sig_atomic_t;
|
||||
// TODO: ssize_t
|
||||
typedef intptr_t ssize_t;
|
||||
|
||||
#if defined(__amd64__) || defined(__aarch64__)
|
||||
typedef int64_t off_t;
|
||||
typedef int64_t off64_t;
|
||||
typedef uint32_t mode_t;
|
||||
typedef uint64_t dev_t;
|
||||
typedef uint64_t ino64_t;
|
||||
typedef uint64_t ino_t;
|
||||
typedef uint32_t nlink_t;
|
||||
typedef int64_t blksize_t;
|
||||
typedef int64_t blkcnt_t;
|
||||
typedef int64_t blkcnt64_t;
|
||||
typedef int64_t time_t;
|
||||
typedef uint32_t uid_t;
|
||||
typedef uint32_t gid_t;
|
||||
typedef int64_t clock_t;
|
||||
typedef int32_t pid_t;
|
||||
#elif defined(__i386__) || defined(__arm__)
|
||||
typedef int32_t off_t;
|
||||
typedef long long off64_t;
|
||||
typedef uint32_t mode_t;
|
||||
typedef int32_t dev_t;
|
||||
typedef int32_t ino64_t;
|
||||
typedef int32_t ino_t;
|
||||
typedef uint32_t nlink_t;
|
||||
typedef int blksize_t;
|
||||
typedef int32_t blkcnt_t;
|
||||
typedef int32_t blkcnt64_t;
|
||||
typedef int32_t time_t;
|
||||
typedef uint32_t uid_t;
|
||||
typedef uint32_t gid_t;
|
||||
typedef long clock_t;
|
||||
typedef int pid_t;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
template <typename T>
|
||||
class ptr_t
|
||||
{
|
||||
T ptr;
|
||||
|
||||
public:
|
||||
ptr_t() : ptr(nullptr) {}
|
||||
ptr_t(T p) : ptr(p) {}
|
||||
ptr_t(int p) : ptr((T)(uintptr_t)p) {}
|
||||
ptr_t(const ptr_t<T> &other) : ptr(other.ptr) {}
|
||||
|
||||
operator T() { return ptr; }
|
||||
operator uintptr_t() { return (uintptr_t)ptr; }
|
||||
|
||||
operator bool() { return (void *)(uintptr_t)ptr != nullptr; }
|
||||
|
||||
ptr_t<T> &operator=(const ptr_t<T> &other)
|
||||
{
|
||||
ptr = other.ptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ptr_t<T> &operator+=(uintptr_t offset)
|
||||
{
|
||||
ptr = (T)((uintptr_t)ptr + offset);
|
||||
return *this;
|
||||
}
|
||||
|
||||
ptr_t<T> &operator-=(uintptr_t offset)
|
||||
{
|
||||
ptr = (T)((uintptr_t)ptr - offset);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const ptr_t<T> &other) const { return ptr == other.ptr; }
|
||||
bool operator==(auto other) const { return (uintptr_t)ptr == (uintptr_t)other; }
|
||||
|
||||
bool operator!=(const ptr_t<T> &other) const { return ptr != other.ptr; }
|
||||
bool operator!=(auto other) const { return (uintptr_t)ptr != (uintptr_t)other; }
|
||||
|
||||
bool operator>(const ptr_t<T> &other) const { return ptr > other.ptr; }
|
||||
bool operator>(auto other) const { return (uintptr_t)ptr > (uintptr_t)other; }
|
||||
|
||||
bool operator<(const ptr_t<T> &other) const { return ptr < other.ptr; }
|
||||
bool operator<(auto other) const { return (uintptr_t)ptr < (uintptr_t)other; }
|
||||
|
||||
bool operator>=(const ptr_t<T> &other) const { return ptr >= other.ptr; }
|
||||
bool operator>=(auto other) const { return (uintptr_t)ptr >= (uintptr_t)other; }
|
||||
|
||||
bool operator<=(const ptr_t<T> &other) const { return ptr <= other.ptr; }
|
||||
bool operator<=(auto other) const { return (uintptr_t)ptr <= (uintptr_t)other; }
|
||||
|
||||
ptr_t<T> operator+(auto offset) const { return ptr_t<T>((void *)((uintptr_t)ptr + offset)); }
|
||||
ptr_t<T> operator-(auto offset) const { return ptr_t<T>((void *)((uintptr_t)ptr - offset)); }
|
||||
|
||||
T operator->() { return ptr; }
|
||||
T operator*() { return *ptr; }
|
||||
};
|
||||
#endif // __cplusplus
|
||||
|
||||
#define INT8_MAX __INT8_MAX__
|
||||
#define INT8_MIN (-INT8_MAX - 1)
|
||||
#define UINT8_MAX __UINT8_MAX__
|
||||
#define INT16_MAX __INT16_MAX__
|
||||
#define INT16_MIN (-INT16_MAX - 1)
|
||||
#define UINT16_MAX __UINT16_MAX__
|
||||
#define INT32_MAX __INT32_MAX__
|
||||
#define INT32_MIN (-INT32_MAX - 1)
|
||||
#define UINT32_MAX __UINT32_MAX__
|
||||
#define INT64_MAX __INT64_MAX__
|
||||
#define INT64_MIN (-INT64_MAX - 1)
|
||||
#define UINT64_MAX __UINT64_MAX__
|
||||
|
||||
#define INT_LEAST8_MAX __INT_LEAST8_MAX__
|
||||
#define INT_LEAST8_MIN (-INT_LEAST8_MAX - 1)
|
||||
#define UINT_LEAST8_MAX __UINT_LEAST8_MAX__
|
||||
#define INT_LEAST16_MAX __INT_LEAST16_MAX__
|
||||
#define INT_LEAST16_MIN (-INT_LEAST16_MAX - 1)
|
||||
#define UINT_LEAST16_MAX __UINT_LEAST16_MAX__
|
||||
#define INT_LEAST32_MAX __INT_LEAST32_MAX__
|
||||
#define INT_LEAST32_MIN (-INT_LEAST32_MAX - 1)
|
||||
#define UINT_LEAST32_MAX __UINT_LEAST32_MAX__
|
||||
#define INT_LEAST64_MAX __INT_LEAST64_MAX__
|
||||
#define INT_LEAST64_MIN (-INT_LEAST64_MAX - 1)
|
||||
#define UINT_LEAST64_MAX __UINT_LEAST64_MAX__
|
||||
|
||||
#define INT_FAST8_MAX __INT_FAST8_MAX__
|
||||
#define INT_FAST8_MIN (-INT_FAST8_MAX - 1)
|
||||
#define UINT_FAST8_MAX __UINT_FAST8_MAX__
|
||||
#define INT_FAST16_MAX __INT_FAST16_MAX__
|
||||
#define INT_FAST16_MIN (-INT_FAST16_MAX - 1)
|
||||
#define UINT_FAST16_MAX __UINT_FAST16_MAX__
|
||||
#define INT_FAST32_MAX __INT_FAST32_MAX__
|
||||
#define INT_FAST32_MIN (-INT_FAST32_MAX - 1)
|
||||
#define UINT_FAST32_MAX __UINT_FAST32_MAX__
|
||||
#define INT_FAST64_MAX __INT_FAST64_MAX__
|
||||
#define INT_FAST64_MIN (-INT_FAST64_MAX - 1)
|
||||
#define UINT_FAST64_MAX __UINT_FAST64_MAX__
|
||||
|
||||
#define INTPTR_MAX __INTPTR_MAX__
|
||||
#define INTPTR_MIN (-INTPTR_MAX - 1)
|
||||
#define UINTPTR_MAX __UINTPTR_MAX__
|
||||
|
||||
#define INTMAX_MAX __INTMAX_MAX__
|
||||
#define INTMAX_MIN (-INTMAX_MAX - 1)
|
||||
#define UINTMAX_MAX __UINTMAX_MAX__
|
||||
|
||||
#define PTRDIFF_MAX __PTRDIFF_MAX__
|
||||
#define PTRDIFF_MIN (-PTRDIFF_MAX - 1)
|
||||
|
||||
#define SIG_ATOMIC_MAX __SIG_ATOMIC_MAX__
|
||||
#define SIG_ATOMIC_MIN __SIG_ATOMIC_MIN__
|
||||
|
||||
#define SIZE_MAX __SIZE_MAX__
|
||||
|
||||
#define WCHAR_MAX __WCHAR_MAX__
|
||||
#define WCHAR_MIN __WCHAR_MIN__
|
||||
|
||||
#define WINT_MAX __WINT_MAX__
|
||||
#define WINT_MIN __WINT_MIN__
|
||||
|
||||
#if defined(__amd64__)
|
||||
#define BREAK __asm__ __volatile__("int $0x3" \
|
||||
: \
|
||||
: \
|
||||
: "memory");
|
||||
#elif defined(__i386__)
|
||||
#define BREAK __asm__ __volatile__("int $0x3" \
|
||||
: \
|
||||
: \
|
||||
: "memory");
|
||||
#elif defined(__aarch64__)
|
||||
#define BREAK __asm__ __volatile__("brk #0" \
|
||||
: \
|
||||
: \
|
||||
: "memory");
|
||||
#endif
|
||||
|
||||
#ifdef __INT48_TYPE__
|
||||
typedef __INT48_TYPE__ int48_t;
|
||||
typedef __UINT48_TYPE__ uint48_t;
|
||||
typedef int48_t int_least48_t;
|
||||
typedef uint48_t uint_least48_t;
|
||||
typedef int48_t int_fast48_t;
|
||||
typedef uint48_t uint_fast48_t;
|
||||
#else // __INT48_TYPE__
|
||||
typedef __INT64_TYPE__ int48_t;
|
||||
typedef __UINT64_TYPE__ uint48_t;
|
||||
typedef int48_t int_least48_t;
|
||||
typedef uint48_t uint_least48_t;
|
||||
typedef int48_t int_fast48_t;
|
||||
typedef uint48_t uint_fast48_t;
|
||||
#endif // __INT48_TYPE__
|
||||
|
||||
#define b4(x) ((x & 0x0F) << 4 | (x & 0xF0) >> 4)
|
||||
#define b8(x) ((x) & 0xFF)
|
||||
#define b16(x) __builtin_bswap16(x)
|
||||
#define b32(x) __builtin_bswap32(x)
|
||||
#define b48(x) (((((x) & 0x0000000000ff) << 40) | \
|
||||
(((x) & 0x00000000ff00) << 24) | \
|
||||
(((x) & 0x000000ff0000) << 8) | \
|
||||
(((x) & 0x0000ff000000) >> 8) | \
|
||||
(((x) & 0x00ff00000000) >> 24) | \
|
||||
(((x) & 0xff0000000000) >> 40)))
|
||||
#define b64(x) __builtin_bswap64(x)
|
||||
|
||||
/* https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html */
|
||||
|
||||
/** No optimization (the default); generates
|
||||
* unoptimized code but has the fastest compilation time.
|
||||
*/
|
||||
#define O0 __attribute__((optimize("O0")))
|
||||
|
||||
/** Moderate optimization;
|
||||
* optimizes reasonably well but does not degrade
|
||||
* compilation time significantly. */
|
||||
#define O1 __attribute__((optimize("O1")))
|
||||
|
||||
/** Full optimization; generates highly
|
||||
* optimized code and has the slowest compilation time.
|
||||
*/
|
||||
#define O2 __attribute__((optimize("O2")))
|
||||
|
||||
/** Full optimization as in -O2;
|
||||
* also uses more aggressive automatic inlining of
|
||||
* subprograms within a unit (Inlining of Subprograms)
|
||||
* and attempts to vectorize loops. */
|
||||
#define O3 __attribute__((optimize("O3")))
|
||||
|
||||
/** Optimize space usage (code and data)
|
||||
* of resulting program.
|
||||
*/
|
||||
#define Os __attribute__((optimize("Os")))
|
||||
|
||||
/** Disregard strict standards compliance.
|
||||
* -Ofast enables all -O3 optimizations.
|
||||
* It also enables optimizations that are not valid for
|
||||
* all standard-compliant programs.
|
||||
*/
|
||||
#define Ofast __attribute__((optimize("Ofast")))
|
||||
|
||||
/** Optimize for size.
|
||||
* -Oz enables all -Os optimizations that do not typically
|
||||
* increase code size.
|
||||
*/
|
||||
#define Oz __attribute__((optimize("Oz")))
|
||||
|
||||
/** Optimize for debugging.
|
||||
* -Og enables optimizations that do not interfere with
|
||||
* debugging.
|
||||
*/
|
||||
#define Og __attribute__((optimize("Og")))
|
||||
|
||||
#define __unused __attribute__((unused))
|
||||
#define __packed __attribute__((packed))
|
||||
#define __naked __attribute__((naked))
|
||||
#define __aligned(x) __attribute__((aligned(x)))
|
||||
#define __section(x) __attribute__((section(x)))
|
||||
#define __noreturn __attribute__((noreturn))
|
||||
#define __weak __attribute__((weak))
|
||||
#define __alias(x) __attribute__((alias(x)))
|
||||
#define __always_inline __attribute__((always_inline))
|
||||
#define __noinline __attribute__((noinline))
|
||||
#define __pure __attribute__((pure))
|
||||
#define __const __attribute__((const))
|
||||
#define __malloc __attribute__((malloc))
|
||||
#define __returns_twice __attribute__((returns_twice))
|
||||
#define __used __attribute__((used))
|
||||
#define __deprecated __attribute__((deprecated))
|
||||
#define __deprecated_msg(x) __attribute__((deprecated(x)))
|
||||
#define __weakref(x) __attribute__((weakref(x)))
|
||||
#define __weakrefalias(x) __attribute__((weakref(#x)))
|
||||
#define __visibility(x) __attribute__((visibility(x)))
|
||||
#define __constructor __attribute__((constructor))
|
||||
#define __destructor __attribute__((destructor))
|
||||
#define __cleanup(x) __attribute__((cleanup(x)))
|
||||
#define __fallthrough __attribute__((fallthrough))
|
||||
#define __nonnull(x) __attribute__((nonnull x))
|
||||
#define __nonnull_all __attribute__((nonnull))
|
||||
#define __returns_nonnull __attribute__((returns_nonnull))
|
||||
#define __sentinel __attribute__((sentinel))
|
||||
#define __sentinel_all __attribute__((sentinel(0)))
|
||||
#define __format(x, y, z) __attribute__((format(x, y, z)))
|
||||
#define __format_arg(x) __attribute__((format_arg(x)))
|
||||
#define __nonnull_params(x) __attribute__((nonnull x))
|
||||
#define __nonnull_all __attribute__((nonnull))
|
||||
#define __warn_unused_result __attribute__((warn_unused_result))
|
||||
#define __no_stack_protector __attribute__((no_stack_protector))
|
||||
#define __no_instrument_function __attribute__((no_instrument_function))
|
||||
#define __no_debug __attribute__((no_debug))
|
||||
#define __target(x) __attribute__((target(x)))
|
||||
#define __min_vector_width(x) __attribute__((min_vector_width(x)))
|
||||
|
||||
// sanitizer
|
||||
#define __no_sanitize(x) __attribute__((no_sanitize(x)))
|
||||
#define __no_sanitize_address __attribute__((no_sanitize_address))
|
||||
#define __no_sanitize_thread __attribute__((no_sanitize_thread))
|
||||
#define __no_sanitize_undefined __attribute__((no_sanitize_undefined))
|
||||
#define __no_sanitize_coverage __attribute__((no_sanitize_coverage))
|
||||
|
||||
#define __synchronize __sync_synchronize()
|
||||
#define __sync __synchronize
|
||||
|
||||
#define __unreachable __builtin_unreachable()
|
||||
|
||||
#define likely(x) __builtin_expect(!!(x), 1)
|
||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
|
||||
#define NoSecurityAnalysis __no_stack_protector __no_sanitize_address __no_sanitize_undefined __no_sanitize_thread
|
||||
#define nsa NoSecurityAnalysis
|
||||
|
||||
#define NIF __no_instrument_function
|
||||
|
||||
#define int3 \
|
||||
__asm__ __volatile__("int3" \
|
||||
: \
|
||||
: \
|
||||
: "memory")
|
||||
|
||||
#define StackPush(stack, type, value) \
|
||||
*((type *)--stack) = value
|
||||
|
||||
#define StackPop(stack, type) \
|
||||
*((type *)stack++)
|
||||
|
||||
#define ReturnLogError(ret, format, ...) \
|
||||
{ \
|
||||
trace(format, ##__VA_ARGS__); \
|
||||
return ret; \
|
||||
} \
|
||||
while (0) \
|
||||
__builtin_unreachable()
|
||||
|
||||
#define AssertReturnError(condition, ret) \
|
||||
do \
|
||||
{ \
|
||||
if (__builtin_expect(!!(!(condition)), 0)) \
|
||||
{ \
|
||||
error("\"%s\" failed!", #condition); \
|
||||
return ret; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif // !__FENNIX_KERNEL_TYPES_H__
|
137
Bootloader/uefi/Makefile
Normal file
137
Bootloader/uefi/Makefile
Normal file
@ -0,0 +1,137 @@
|
||||
BOOT_FILENAME = BOOTX64.EFI
|
||||
|
||||
GNUEFI_RELEASE_VERSION=3.0.18
|
||||
|
||||
GIT_COMMIT = $(shell git rev-parse HEAD)
|
||||
GIT_COMMIT_SHORT = $(shell git rev-parse --short HEAD)
|
||||
|
||||
HEADERS := $(sort $(dir $(wildcard ../include/*)))
|
||||
INCLUDE_DIR = -I../include
|
||||
|
||||
define find-sources
|
||||
$(shell find ./ -type f -name '$1' -print0 | xargs -0)
|
||||
endef
|
||||
|
||||
BMP_SOURCES := $(call find-sources,*.bmp)
|
||||
PSF_SOURCES := $(call find-sources,*.psf)
|
||||
S_SOURCES := $(call find-sources,*.S)
|
||||
s_SOURCES := $(call find-sources,*.s)
|
||||
C_SOURCES := $(call find-sources,*.c)
|
||||
CXX_SOURCES := $(call find-sources,*.cpp)
|
||||
|
||||
OBJ = $(BMP_SOURCES:.bmp=.o) $(PSF_SOURCES:.psf=.o) $(s_SOURCES:.s=.o) $(S_SOURCES:.S=.o) $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o)
|
||||
|
||||
LDFLAGS = -static -nostdlib -nodefaultlibs -nolibc \
|
||||
-Wl,-static,--no-dynamic-linker,-ztext \
|
||||
-zmax-page-size=0x1000 \
|
||||
-Wl,-Map kernel.map -fno-pic -fno-pie
|
||||
|
||||
# Disable all warnings by adding "-w" in WARNCFLAG and if you want to treat the warnings as errors, add "-Werror"
|
||||
# -Wconversion this may be re-added later
|
||||
WARNCFLAG = -Wall -Wextra \
|
||||
-Wfloat-equal -Wpointer-arith -Wcast-align \
|
||||
-Wredundant-decls -Winit-self -Wswitch-default \
|
||||
-Wstrict-overflow=5 -Wno-error=cpp -Werror \
|
||||
-Wno-unused-parameter -Wno-error=format
|
||||
|
||||
CFLAG_STACK_PROTECTOR := -fstack-protector-all
|
||||
|
||||
# https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html
|
||||
CFLAGS := \
|
||||
$(INCLUDE_DIR) \
|
||||
-D__kernel__='1' \
|
||||
-DKERNEL_NAME='"$(OSNAME)"' \
|
||||
-DKERNEL_ARCH='"$(OSARCH)"' \
|
||||
-DKERNEL_VERSION='"$(KERNEL_VERSION)"' \
|
||||
-DGIT_COMMIT='"$(GIT_COMMIT)"' \
|
||||
-DGIT_COMMIT_SHORT='"$(GIT_COMMIT_SHORT)"' \
|
||||
-fno-pic -fno-pie -fno-builtin
|
||||
|
||||
ifeq ($(OSARCH), amd64)
|
||||
CFLAGS += -march=core2 -mcmodel=kernel -m64 -mno-red-zone
|
||||
LDFLAGS += -T../linker.ld
|
||||
else ifeq ($(OSARCH), i386)
|
||||
CFLAGS += -march=pentium -m32 -mno-red-zone
|
||||
LDFLAGS += -T../linker.ld
|
||||
else ifeq ($(OSARCH), arm)
|
||||
CFLAGS += -march=armv7-a -mfloat-abi=softfp -ggdb3
|
||||
LDFLAGS += -T../linker.ld
|
||||
WARNCFLAG += -w
|
||||
else ifeq ($(OSARCH), aarch64)
|
||||
CFLAGS += -march=armv9.4-a -mtune=cortex-a72 -mlittle-endian -mcmodel=large
|
||||
LDFLAGS += -T../linker.ld
|
||||
endif # OSARCH
|
||||
|
||||
# -finstrument-functions for __cyg_profile_func_enter & __cyg_profile_func_exit. Used for profiling and debugging.
|
||||
ifeq ($(DEBUG), 1)
|
||||
# CFLAGS += --coverage
|
||||
# CFLAGS += -pg
|
||||
# CFLAGS += -finstrument-functions
|
||||
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage -fsanitize=undefined
|
||||
ifeq ($(OSARCH), amd64)
|
||||
CFLAGS += -fverbose-asm
|
||||
endif # amd64
|
||||
ifeq ($(OSARCH), arm)
|
||||
CFLAGS += -fstack-check -fverbose-asm
|
||||
endif # arm
|
||||
ifeq ($(OSARCH), aarch64)
|
||||
CFLAGS += -fstack-check -fverbose-asm
|
||||
endif # aarch64
|
||||
LDFLAGS += -ggdb3 -O0
|
||||
ASFLAGS += -g --gstabs+ --gdwarf-5 -D
|
||||
WARNCFLAG += -Wno-unused-function -Wno-maybe-uninitialized -Wno-builtin-declaration-mismatch -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-variable
|
||||
endif # DEBUG
|
||||
|
||||
default:
|
||||
$(error Do not run this Makefile directly!)
|
||||
|
||||
build: $(BOOT_FILENAME)
|
||||
|
||||
$(BOOT_FILENAME): $(OBJ)
|
||||
$(info Linking $@)
|
||||
$(LD) -shared -Bsymbolic -L../gnu-efi/x86_64/lib -L../gnu-efi/x86_64/gnuefi -T../gnu-efi/gnuefi/elf_x86_64_efi.lds ../gnu-efi/x86_64/gnuefi/crt0-efi-x86_64.o $(OBJ) -o tmp.so -lgnuefi -lefi
|
||||
objcopy -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela -j .rel.* -j .rela.* -j .reloc --target efi-app-x86_64 --subsystem=10 tmp.so BOOTX64.EFI
|
||||
rm tmp.so
|
||||
|
||||
%.o: %.c $(HEADERS)
|
||||
$(info Compiling $<)
|
||||
$(CC) -I../include -fpic -ffreestanding -fno-stack-protector -fno-stack-check -fshort-wchar -mno-red-zone -maccumulate-outgoing-args -c $< -o $@
|
||||
|
||||
%.o: %.cpp $(HEADERS)
|
||||
$(info Compiling $<)
|
||||
$(CC) -I../include -fpic -ffreestanding -fno-stack-protector -fno-stack-check -fshort-wchar -mno-red-zone -maccumulate-outgoing-args -c $< -o $@
|
||||
|
||||
%.o: %.S
|
||||
$(info Compiling $<)
|
||||
$(AS) $(ASFLAGS) -c $< -o $@
|
||||
|
||||
%.o: %.s
|
||||
$(info Compiling $<)
|
||||
$(AS) $(ASFLAGS) -c $< -o $@
|
||||
|
||||
%.o: %.psf
|
||||
ifeq ($(OSARCH), amd64)
|
||||
$(OBJCOPY) -O elf64-x86-64 -I binary $< $@
|
||||
else ifeq ($(OSARCH), i386)
|
||||
$(OBJCOPY) -O elf32-i386 -I binary $< $@
|
||||
else ifeq ($(OSARCH), arm)
|
||||
$(OBJCOPY) -O elf32-littlearm -I binary $< $@
|
||||
else ifeq ($(OSARCH), aarch64)
|
||||
$(OBJCOPY) -O elf64-littleaarch64 -I binary $< $@
|
||||
endif
|
||||
$(NM) $@
|
||||
|
||||
%.o: %.bmp
|
||||
ifeq ($(OSARCH), amd64)
|
||||
$(OBJCOPY) -O elf64-x86-64 -I binary $< $@
|
||||
else ifeq ($(OSARCH), i386)
|
||||
$(OBJCOPY) -O elf32-i386 -I binary $< $@
|
||||
else ifeq ($(OSARCH), arm)
|
||||
$(OBJCOPY) -O elf32-littlearm -I binary $< $@
|
||||
else ifeq ($(OSARCH), aarch64)
|
||||
$(OBJCOPY) -O elf64-littlearch64 -I binary $< $@
|
||||
endif
|
||||
$(NM) $@
|
||||
|
||||
clean:
|
||||
rm -f kernel.map kernel_dump.map kernel_dump_intel.map $(OBJ) $(STACK_USAGE_OBJ) $(GCNO_OBJ) $(BOOT_FILENAME)
|
27
Bootloader/uefi/main.c
Normal file
27
Bootloader/uefi/main.c
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
This file is part of Lynx Bootloader.
|
||||
|
||||
Lynx Bootloader is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Lynx Bootloader is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Lynx Bootloader. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
|
||||
EFI_STATUS EFIAPI efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
|
||||
{
|
||||
InitializeLib(ImageHandle, SystemTable);
|
||||
SystemTable->BootServices->SetWatchdogTimer(0, 0, 0, NULL);
|
||||
Print(L"Lynx Bootloader © EnderIce2 2025\n");
|
||||
return EFI_SUCCESS;
|
||||
}
|
1883
CHANGELOG.md
Normal file
1883
CHANGELOG.md
Normal file
File diff suppressed because it is too large
Load Diff
128
CODE_OF_CONDUCT.md
Normal file
128
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,128 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, religion, or sexual identity
|
||||
and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the
|
||||
overall community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or
|
||||
advances of any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email
|
||||
address, without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
enderice2@protonmail.com.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series
|
||||
of actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or
|
||||
permanent ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within
|
||||
the community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.0, available at
|
||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
||||
|
||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
||||
enforcement ladder](https://github.com/mozilla/diversity).
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
https://www.contributor-covenant.org/faq. Translations are available at
|
||||
https://www.contributor-covenant.org/translations.
|
72
CONTRIBUTING.md
Normal file
72
CONTRIBUTING.md
Normal file
@ -0,0 +1,72 @@
|
||||
# Contributing to Fennix
|
||||
|
||||
We welcome contributions to Fennix! Whether you are reporting a bug, suggesting a feature, or submitting a pull request, we’re excited to collaborate with you.
|
||||
|
||||
## Table of Contents
|
||||
- [How to Contribute](#how-to-contribute)
|
||||
- [Code of Conduct](#code-of-conduct)
|
||||
- [Getting Started](#getting-started)
|
||||
- [Pull Request Guidelines](#pull-request-guidelines)
|
||||
- [Reporting Issues](#reporting-issues)
|
||||
- [Style Guide](#style-guide)
|
||||
|
||||
---
|
||||
|
||||
## How to Contribute
|
||||
|
||||
1. **Check existing issues or discussions** to see if your idea has already been mentioned or if someone is already working on it.
|
||||
2. If you’re new to the project, consider contributing to [good first issues](https://github.com/EnderIce2/Fennix/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22).
|
||||
3. Fork the repository and create a new branch for your changes.
|
||||
|
||||
---
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
By participating in this project, you agree to abide by our [Code of Conduct](CODE_OF_CONDUCT.md). Be respectful and inclusive while interacting with the community.
|
||||
|
||||
---
|
||||
|
||||
## Getting Started
|
||||
|
||||
1. Fork this repository and clone your fork.
|
||||
2. Set up your development environment according to the [README.md](README.md) or any other setup guide provided.
|
||||
3. Ensure all tests pass before submitting changes. Add tests for new features where applicable.
|
||||
|
||||
---
|
||||
|
||||
## Pull Request Guidelines
|
||||
|
||||
1. Keep pull requests focused on a single issue or feature.
|
||||
2. Write clear, descriptive commit messages.
|
||||
3. Ensure all tests pass before submitting your PR.
|
||||
4. Include a detailed description of your changes and reference any relevant issue numbers.
|
||||
5. Be open to feedback and revise your pull request if requested.
|
||||
6. Mark your pull request as a draft if it’s still a work in progress.
|
||||
|
||||
---
|
||||
|
||||
## Reporting Issues
|
||||
|
||||
1. Check if the issue has already been reported.
|
||||
2. Include a clear and descriptive title.
|
||||
3. Provide detailed steps to reproduce the problem (if applicable).
|
||||
4. Mention your environment details (e.g., OS, version, etc.).
|
||||
5. Attach screenshots or logs if they help explain the issue.
|
||||
|
||||
---
|
||||
|
||||
## Style Guide
|
||||
|
||||
Follow the coding style used in the repository to ensure consistency. Adhere to:
|
||||
- Use CamelCase for all names.
|
||||
- Start function and global declaration names with an uppercase letter.
|
||||
- Start local variable names with a lowercase letter.
|
||||
- Maintain consistent formatting and commenting guidelines.
|
||||
- Commit messages must follow [Conventional Commits](https://conventionalcommits.org).
|
||||
- Release versions must follow [Semantic Versioning](https://semver.org).
|
||||
|
||||
Refer to the [style guide document](STYLE_GUIDE.md) if available.
|
||||
|
||||
---
|
||||
|
||||
Thank you for contributing! Your effort makes Fennix better for everyone. If you have any questions, feel free to reach out by opening an issue or joining our discussions.
|
140
CREDITS.md
Normal file
140
CREDITS.md
Normal file
@ -0,0 +1,140 @@
|
||||
# Credits and References
|
||||
|
||||
This project has been influenced and inspired by other projects and resources.
|
||||
|
||||
License information can be found in the [LICENSES.md](LICENSES.md) file.
|
||||
|
||||
## General
|
||||
- [OSDev Wiki](https://wiki.osdev.org/Main_Page)
|
||||
- [GCC x86 Built-in Functions](https://gcc.gnu.org/onlinedocs/gcc/x86-Built-in-Functions.html#x86-Built-in-Functions)
|
||||
- [GCC Common Function Attributes](https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes)
|
||||
- [LemonOS Project](https://github.com/LemonOSProject/LemonOS)
|
||||
- [ToaruOS](https://github.com/klange/toaruos)
|
||||
- [Various SIMD functions](https://wiki.osdev.org/User:01000101/optlib/)
|
||||
|
||||
## C++ STL
|
||||
- [cppreference.com](https://cppreference.com)
|
||||
|
||||
## Virtual terminal
|
||||
- [vtconsole](https://github.com/sleepy-monax/vtconsole)
|
||||
|
||||
## Font
|
||||
- [Tamsyn Font](http://www.fial.com/~scott/tamsyn-font/)
|
||||
|
||||
## CPU XCR0 Structure
|
||||
- [CPU Registers x86 - XCR0](https://wiki.osdev.org/CPU_Registers_x86#XCR0)
|
||||
|
||||
## CPUID 0x7
|
||||
- [CPUID](https://en.wikipedia.org/wiki/CPUID)
|
||||
|
||||
## KVM CPUID
|
||||
- [kernel.org KVM CPUID](https://www.kernel.org/doc/html/v6.9/virt/kvm/x86/cpuid.html?highlight=cpuid)
|
||||
|
||||
## Network
|
||||
- [Beej's Guide to Network Programming](https://web.archive.org/web/20051210132103/http://users.pcnet.ro/dmoroian/beej/Beej.html)
|
||||
- [UDP Socket Programming](https://web.archive.org/web/20060229214053/http://www.cs.rutgers.edu/~pxk/417/notes/sockets/udp.html)
|
||||
- [EtherType](https://en.wikipedia.org/wiki/EtherType)
|
||||
- [Linux Network Packet Reception](https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/performance_tuning_guide/s-network-packet-reception)
|
||||
- [Linux Kernel Networking Labs](https://linux-kernel-labs.github.io/refs/heads/master/labs/networking.html)
|
||||
- [smoltcp](https://github.com/smoltcp-rs/smoltcp)
|
||||
- [Understanding Linux Network Internals](https://www.cs.unh.edu/~cruse/cs326f04/RTL8139D_DataSheet.pdf)
|
||||
- [Address Resolution Protocol (ARP)](https://en.wikipedia.org/wiki/Address_Resolution_Protocol)
|
||||
- [C++ Operators](https://en.cppreference.com/w/cpp/language/operators)
|
||||
- [Dynamic Host Configuration Protocol (DHCP)](https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol)
|
||||
- [RTL8139 Programmer's Guide](https://www.cs.usfca.edu/~cruse/cs326f04/RTL8139_ProgrammersGuide.pdf)
|
||||
- [RTL8139CP Datasheet](http://realtek.info/pdf/rtl8139cp.pdf)
|
||||
- [IPv4](https://en.wikipedia.org/wiki/IPv4)
|
||||
- [ICMP Parameters](https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml)
|
||||
|
||||
## Loading ELF Shared Libraries and Dynamic Linking
|
||||
- [How To Write Shared Libraries](https://www.akkadia.org/drepper/dsohowto.pdf)
|
||||
- [Dynamic Linker](https://wiki.osdev.org/Dynamic_Linker)
|
||||
- [Nightingale OS](https://github.com/tyler569/nightingale)
|
||||
- [PLT and GOT: The Key to Code Sharing and Dynamic Libraries](https://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html)
|
||||
- [YouTube Video on Dynamic Linking](https://www.youtube.com/watch?v=kUk5pw4w0h4)
|
||||
- [Oracle: Position Independent Code](https://docs.oracle.com/cd/E19683-01/817-3677/chapter6-42444/index.html)
|
||||
- [PLT and GOT Explained](https://ir0nstone.gitbook.io/notes/types/stack/aslr/plt_and_got)
|
||||
|
||||
## Inter-Process Communication (IPC)
|
||||
- [Oracle IPC](https://docs.oracle.com/cd/E19048-01/chorus5/806-6897/architecture-103/index.html)
|
||||
- [Inter-Process Communication in OS](https://www.scaler.com/topics/operating-system/inter-process-communication-in-os/)
|
||||
- [IPC on Wikipedia](https://en.wikipedia.org/wiki/Inter-process_communication)
|
||||
- [GeeksforGeeks IPC Guide](https://www.geeksforgeeks.org/inter-process-communication-ipc/)
|
||||
|
||||
## PCI (Peripheral Component Interconnect)
|
||||
- [OSDev PCI](https://wiki.osdev.org/PCI)
|
||||
- [PCI Configuration Space](https://en.wikipedia.org/wiki/PCI_configuration_space)
|
||||
|
||||
## Audio
|
||||
- [FFmpeg Audio Types](https://trac.ffmpeg.org/wiki/audio%20types)
|
||||
- [AC97 on OSDev](https://wiki.osdev.org/AC97)
|
||||
- [AC97 Revision 2.3 Specification](https://inst.eecs.berkeley.edu//~cs150/Documents/ac97_r23.pdf)
|
||||
|
||||
## Intrinsics (x86)
|
||||
- [Microsoft x86 Intrinsics](https://learn.microsoft.com/en-us/cpp/intrinsics/x86-intrinsics-list)
|
||||
- [Intel Intrinsics Guide](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html)
|
||||
|
||||
## CPUID Information
|
||||
- [AMD CPUID Instruction](https://www.amd.com/system/files/TechDocs/40332.pdf)
|
||||
- [CPUID Instruction Note](https://www.scss.tcd.ie/~jones/CS4021/processor-identification-cpuid-instruction-note.pdf)
|
||||
|
||||
## SMBIOS (System Management BIOS)
|
||||
- [DMTF DSP0134](https://www.dmtf.org/dsp/DSP0134)
|
||||
- [DSP0134 Version 3.6.0](https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.6.0.pdf)
|
||||
- [OSDev SMBIOS](https://wiki.osdev.org/System_Management_BIOS)
|
||||
|
||||
## EDBA (Effective Direct Bus Access)
|
||||
- [Memory Map (x86)](https://wiki.osdev.org/Memory_Map_(x86))
|
||||
|
||||
## UMIP, SMAP, and SMEP
|
||||
- [Control Register on Wikipedia](https://en.wikipedia.org/wiki/Control_register)
|
||||
- [Control Register and UMIP](https://web.archive.org/web/20160312223150/http://ncsi.com/nsatc11/presentations/wednesday/emerging_technologies/fischer.pdf)
|
||||
- [Supervisor Mode Access Prevention (SMEP)](https://en.wikipedia.org/wiki/Supervisor_Mode_Access_Prevention)
|
||||
|
||||
## Atomic Operations
|
||||
- [C++ Atomic Operations](https://en.cppreference.com/w/cpp/atomic/atomic)
|
||||
|
||||
## ELF (Executable and Linkable Format)
|
||||
- [ELF Header Format](https://www.sco.com/developers/gabi/latest/ch4.eheader.html)
|
||||
- [ELF File Format Specification](https://refspecs.linuxfoundation.org/elf/elf.pdf)
|
||||
- [Oracle: Executable and Linkable Format](https://docs.oracle.com/cd/E19683-01/817-3677/chapter6-42444/index.html)
|
||||
- [Oracle: ELF Program Headers](https://docs.oracle.com/cd/E19683-01/816-1386/chapter6-83432/index.html)
|
||||
- [YouTube Video on ELF](https://www.youtube.com/watch?v=nC1U1LJQL8o)
|
||||
- [Stevens' UNIX Network Programming](https://stevens.netmeister.org/631/elf.html)
|
||||
- [Linux Kernel ELF Header](https://github.com/torvalds/linux/blob/master/include/uapi/linux/elf.h)
|
||||
|
||||
## C++ ABI (Application Binary Interface)
|
||||
- [GCC libstdc++ Source](https://github.com/gcc-mirror/gcc/tree/master/libstdc%2B%2B-v3)
|
||||
- [Itanium C++ ABI](https://itanium-cxx-abi.github.io/cxx-abi/abi.html)
|
||||
|
||||
## signal.h
|
||||
- [POSIX signal.h](https://pubs.opengroup.org/onlinepubs/009695399/basedefs/signal.h.html)
|
||||
- [Linux signal(7) Manual](https://man7.org/linux/man-pages/man7/signal.7.html)
|
||||
|
||||
## PS/2
|
||||
- [Scan Codes](https://www.win.tue.nl/~aeb/linux/kbd/scancodes-11.html)
|
||||
- [PS/2 Keyboard on OSDev](https://wiki.osdev.org/PS2_Keyboard)
|
||||
- [PS/2 Mouse on OSDev](https://wiki.osdev.org/PS2_Mouse)
|
||||
- [Mouse Input on OSDev](https://wiki.osdev.org/Mouse_Input)
|
||||
- [I/O Ports on OSDev](https://wiki.osdev.org/I/O_ports)
|
||||
- [PS/2 Controller on OSDev](https://wiki.osdev.org/%228042%22_PS/2_Controller)
|
||||
- [AIP on OSDev](https://wiki.osdev.org/Advanced_Integrated_Peripheral)
|
||||
|
||||
## UART
|
||||
- [Interfacing the Serial / RS232 Port V5.0](http://www.senet.com.au/~cpeacock)
|
||||
|
||||
## UEFI
|
||||
- [U-Boot EFI Commands](https://docs.u-boot.org/en/latest/usage/cmd/efi.html)
|
||||
- [UEFI Specification 2.10](https://uefi.org/sites/default/files/resources/UEFI_Spec_2_10_Aug29.pdf)
|
||||
- [UEFI Boot Process Overview](https://gist.github.com/Velocet/d394281d96191e235ff46a8aa2018d80)
|
||||
- [Rust OS Development: UEFI](https://blog.malware.re/2023/09/01/rust-os-part2/index.html)
|
||||
- [GUIDs Database](https://github.com/DSecurity/efiSeek/blob/master/data/guids-db.ini)
|
||||
|
||||
## BGRT
|
||||
- [BGRT on OSDev](https://wiki.osdev.org/BGRT)
|
||||
- [BMP File Structure @ Gdansk University of Technology](http://www.ue.eti.pg.gda.pl/fpgalab/zadania.spartan3/zad_vga_struktura_pliku_bmp_en.html)
|
||||
- [BGRT @ Purdue University](https://engineering.purdue.edu/ece264/16au/hw/HW13)
|
||||
|
||||
---
|
||||
|
||||
Special thanks to all contributors and the creators of the referenced projects and resources!
|
42
Doxyfile
42
Doxyfile
@ -44,14 +44,14 @@ PROJECT_NUMBER = 1.0.0
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
# quick idea about the purpose of the project. Keep the description short.
|
||||
|
||||
PROJECT_BRIEF = "Opeating System from scratch made in C and C++"
|
||||
PROJECT_BRIEF = "Full Documentation"
|
||||
|
||||
# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
|
||||
# in the documentation. The maximum height of the logo should not exceed 55
|
||||
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
|
||||
# the logo to the output directory.
|
||||
|
||||
PROJECT_LOGO =
|
||||
PROJECT_LOGO = tools/doxygen/favicon.ico
|
||||
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
|
||||
# into which the generated documentation will be written. If a relative path is
|
||||
@ -246,7 +246,7 @@ INHERIT_DOCS = YES
|
||||
# of the file/class/namespace that contains it.
|
||||
# The default value is: NO.
|
||||
|
||||
SEPARATE_MEMBER_PAGES = YES
|
||||
SEPARATE_MEMBER_PAGES = NO
|
||||
|
||||
# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
|
||||
# uses this value to replace tabs by spaces in code fragments.
|
||||
@ -424,7 +424,7 @@ SUBGROUPING = YES
|
||||
# SEPARATE_MEMBER_PAGES.
|
||||
# The default value is: NO.
|
||||
|
||||
INLINE_GROUPED_CLASSES = YES
|
||||
INLINE_GROUPED_CLASSES = NO
|
||||
|
||||
# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
|
||||
# with only public data fields or simple typedef fields will be shown inline in
|
||||
@ -614,7 +614,7 @@ HIDE_COMPOUND_REFERENCE= NO
|
||||
# the files that are included by a file in the documentation of that file.
|
||||
# The default value is: YES.
|
||||
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
SHOW_INCLUDE_FILES = NO
|
||||
|
||||
# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
|
||||
# grouped member an include statement to the documentation, telling the reader
|
||||
@ -794,7 +794,7 @@ CITE_BIB_FILES =
|
||||
# messages are off.
|
||||
# The default value is: NO.
|
||||
|
||||
QUIET = NO
|
||||
QUIET = YES
|
||||
|
||||
# The WARNINGS tag can be used to turn on/off the warning messages that are
|
||||
# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
|
||||
@ -864,7 +864,14 @@ WARN_LOGFILE =
|
||||
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
|
||||
# Note: If this tag is empty the current directory is searched.
|
||||
|
||||
INPUT = Kernel Lynx Userspace Drivers tools/doxymds/main.md
|
||||
INPUT = tools/doxygen/index.md \
|
||||
tools/doxygen/api.md \
|
||||
tools/doxygen/develop.md \
|
||||
README \
|
||||
Userspace/README.md \
|
||||
Drivers/README.md \
|
||||
Kernel/README.md \
|
||||
Kernel/include/interface
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||
@ -955,7 +962,7 @@ RECURSIVE = YES
|
||||
# Note that relative paths are relative to the directory from which doxygen is
|
||||
# run.
|
||||
|
||||
EXCLUDE = .vscode tools
|
||||
EXCLUDE = .vscode .github
|
||||
|
||||
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
|
||||
# directories that are symbolic links (a Unix file system feature) are excluded
|
||||
@ -1064,7 +1071,7 @@ FILTER_SOURCE_PATTERNS =
|
||||
# (index.html). This can be useful if you have a project on for instance GitHub
|
||||
# and want to reuse the introduction page also for the doxygen output.
|
||||
|
||||
USE_MDFILE_AS_MAINPAGE = tools/doxymds/main.md
|
||||
USE_MDFILE_AS_MAINPAGE = tools/doxygen/index.md
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to source browsing
|
||||
@ -1224,7 +1231,7 @@ GENERATE_HTML = YES
|
||||
# The default directory is: html.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_OUTPUT = doxygen-doc/fulldoc
|
||||
HTML_OUTPUT = doxygen-doc/docs
|
||||
|
||||
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
|
||||
# generated HTML page (for example: .htm, .php, .asp).
|
||||
@ -1251,7 +1258,7 @@ HTML_FILE_EXTENSION = .html
|
||||
# of the possible markers and block names see the documentation.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_HEADER =
|
||||
HTML_HEADER = tools/doxygen/header.html
|
||||
|
||||
# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
|
||||
# generated HTML page. If the tag is left blank doxygen will generate a standard
|
||||
@ -1286,7 +1293,8 @@ HTML_STYLESHEET =
|
||||
# list). For an example see the documentation.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_EXTRA_STYLESHEET = tools/doxygen-awesome.css tools/custom.css
|
||||
HTML_EXTRA_STYLESHEET = tools/doxygen/theme/doxygen-awesome.css \
|
||||
tools/doxygen/custom.css
|
||||
|
||||
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
|
||||
# other source files which should be copied to the HTML output directory. Note
|
||||
@ -1296,7 +1304,11 @@ HTML_EXTRA_STYLESHEET = tools/doxygen-awesome.css tools/custom.css
|
||||
# files will be copied as-is; there are no commands or markers available.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_EXTRA_FILES =
|
||||
HTML_EXTRA_FILES = tools/doxygen/theme/doxygen-awesome-darkmode-toggle.js \
|
||||
tools/doxygen/theme/doxygen-awesome-fragment-copy-button.js \
|
||||
tools/doxygen/theme/doxygen-awesome-paragraph-link.js \
|
||||
tools/doxygen/theme/doxygen-awesome-interactive-toc.js \
|
||||
tools/doxygen/theme/doxygen-awesome-tabs.js
|
||||
|
||||
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
|
||||
# will adjust the colors in the style sheet and background images according to
|
||||
@ -1335,7 +1347,7 @@ HTML_COLORSTYLE_GAMMA = 80
|
||||
# The default value is: NO.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
||||
HTML_TIMESTAMP = NO
|
||||
HTML_TIMESTAMP = YES
|
||||
|
||||
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
|
||||
# documentation will contain a main index with vertical navigation menus that
|
||||
@ -2071,7 +2083,7 @@ MAN_OUTPUT = man
|
||||
# The default value is: .3.
|
||||
# This tag requires that the tag GENERATE_MAN is set to YES.
|
||||
|
||||
MAN_EXTENSION = .3
|
||||
MAN_EXTENSION = .2
|
||||
|
||||
# The MAN_SUBDIR tag determines the name of the directory created within
|
||||
# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
|
||||
|
13
Drivers/.editorconfig
Normal file
13
Drivers/.editorconfig
Normal file
@ -0,0 +1,13 @@
|
||||
# EditorConfig is awesome: https://editorconfig.org
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
indent_style = tab
|
||||
indent_size = 4
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
253
Drivers/.vscode/c_cpp_properties.json
vendored
253
Drivers/.vscode/c_cpp_properties.json
vendored
@ -1,120 +1,137 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Fennix x64 (Linux, GCC, debug)",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/include",
|
||||
"${workspaceFolder}/include/**"
|
||||
],
|
||||
"defines": [
|
||||
"__debug_vscode__",
|
||||
"KERNEL_NAME=\"Fennix\"",
|
||||
"KERNEL_VERSION=\"1.0\"",
|
||||
"GIT_COMMIT=\"0000000000000000000000000000000000000000\"",
|
||||
"GIT_COMMIT_SHORT=\"0000000\"",
|
||||
"a64",
|
||||
"DEBUG=\"1\""
|
||||
],
|
||||
"compilerPath": "${workspaceFolder}/../tools/cross/bin/x86_64-fennix-gcc",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++20",
|
||||
"intelliSenseMode": "gcc-x64",
|
||||
"configurationProvider": "ms-vscode.makefile-tools",
|
||||
"compilerArgs": [
|
||||
// Compiler flags
|
||||
"-fPIC",
|
||||
"-fPIE",
|
||||
"-pie",
|
||||
"-mno-80387",
|
||||
"-mno-mmx",
|
||||
"-mno-3dnow",
|
||||
"-mno-red-zone",
|
||||
"-mno-sse",
|
||||
"-mno-sse2",
|
||||
"-march=x86-64",
|
||||
"-pipe",
|
||||
"-ffunction-sections",
|
||||
"-msoft-float",
|
||||
"-fno-builtin",
|
||||
|
||||
// C++ flags
|
||||
"-fexceptions",
|
||||
|
||||
// Linker flags
|
||||
"-fPIC",
|
||||
"-fPIE",
|
||||
"-pie",
|
||||
"-Wl,-eDriverEntry",
|
||||
"-Wl,-static,--no-dynamic-linker,-ztext,--no-warn-rwx-segment",
|
||||
"-nostdlib",
|
||||
"-nodefaultlibs",
|
||||
"-nolibc",
|
||||
"-zmax-page-size=0x1000",
|
||||
"-static",
|
||||
|
||||
// VSCode flags
|
||||
"-ffreestanding",
|
||||
"-nostdinc",
|
||||
"-nostdinc++"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Fennix x32 (Linux, GCC, debug)",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/include/**"
|
||||
],
|
||||
"defines": [
|
||||
"__debug_vscode__",
|
||||
"KERNEL_NAME=\"Fennix\"",
|
||||
"KERNEL_VERSION=\"1.0\"",
|
||||
"GIT_COMMIT=\"0000000000000000000000000000000000000000\"",
|
||||
"GIT_COMMIT_SHORT=\"0000000\"",
|
||||
"a32",
|
||||
"DEBUG=\"1\""
|
||||
],
|
||||
"compilerPath": "${workspaceFolder}/../tools/cross/bin/i386-elf-gcc",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++20",
|
||||
"intelliSenseMode": "gcc-x86",
|
||||
"configurationProvider": "ms-vscode.makefile-tools",
|
||||
"compilerArgs": [
|
||||
// Compiler flags
|
||||
"-fPIC",
|
||||
"-fPIE",
|
||||
"-pie",
|
||||
"-mno-80387",
|
||||
"-mno-mmx",
|
||||
"-mno-3dnow",
|
||||
"-mno-red-zone",
|
||||
"-mno-sse",
|
||||
"-mno-sse2",
|
||||
"-march=i386",
|
||||
"-pipe",
|
||||
"-ffunction-sections",
|
||||
"-msoft-float",
|
||||
"-fno-builtin",
|
||||
|
||||
// C++ flags
|
||||
"-fexceptions",
|
||||
|
||||
// Linker flags
|
||||
"-fPIC",
|
||||
"-fPIE",
|
||||
"-pie",
|
||||
"-Wl,-eDriverEntry",
|
||||
"-Wl,-static,--no-dynamic-linker,-ztext,--no-warn-rwx-segment",
|
||||
"-nostdlib",
|
||||
"-nodefaultlibs",
|
||||
"-nolibc",
|
||||
"-zmax-page-size=0x1000",
|
||||
"-static",
|
||||
|
||||
// VSCode flags
|
||||
"-ffreestanding",
|
||||
"-nostdinc",
|
||||
"-nostdinc++"
|
||||
]
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Fennix x64 (Linux, GCC, debug)",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/include",
|
||||
"${workspaceFolder}/include/**"
|
||||
],
|
||||
"defines": [
|
||||
"__debug_vscode__",
|
||||
"KERNEL_NAME=\"Fennix\"",
|
||||
"KERNEL_VERSION=\"1.0\"",
|
||||
"GIT_COMMIT=\"0000000000000000000000000000000000000000\"",
|
||||
"GIT_COMMIT_SHORT=\"0000000\"",
|
||||
"DEBUG=\"1\""
|
||||
],
|
||||
"compilerPath": "${workspaceFolder}/../tools/cross/bin/x86_64-fennix-gcc",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++20",
|
||||
"intelliSenseMode": "gcc-x64",
|
||||
"configurationProvider": "ms-vscode.makefile-tools",
|
||||
"compilerArgs": [
|
||||
// Compiler flags
|
||||
"-fPIC",
|
||||
"-fPIE",
|
||||
"-pie",
|
||||
"-mno-80387",
|
||||
"-mno-mmx",
|
||||
"-mno-3dnow",
|
||||
"-mno-red-zone",
|
||||
"-mno-sse",
|
||||
"-mno-sse2",
|
||||
"-march=x86-64",
|
||||
"-pipe",
|
||||
"-ffunction-sections",
|
||||
"-msoft-float",
|
||||
"-fno-builtin",
|
||||
// C++ flags
|
||||
"-fexceptions",
|
||||
// Linker flags
|
||||
"-fPIC",
|
||||
"-fPIE",
|
||||
"-pie",
|
||||
"-Wl,-eDriverEntry",
|
||||
"-Wl,-static,--no-dynamic-linker,-ztext,--no-warn-rwx-segment",
|
||||
"-nostdlib",
|
||||
"-nodefaultlibs",
|
||||
"-nolibc",
|
||||
"-zmax-page-size=0x1000",
|
||||
"-static",
|
||||
// VSCode flags
|
||||
"-ffreestanding",
|
||||
"-nostdinc",
|
||||
"-nostdinc++"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Fennix x32 (Linux, GCC, debug)",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/include/**"
|
||||
],
|
||||
"defines": [
|
||||
"__debug_vscode__",
|
||||
"KERNEL_NAME=\"Fennix\"",
|
||||
"KERNEL_VERSION=\"1.0\"",
|
||||
"GIT_COMMIT=\"0000000000000000000000000000000000000000\"",
|
||||
"GIT_COMMIT_SHORT=\"0000000\"",
|
||||
"DEBUG=\"1\""
|
||||
],
|
||||
"compilerPath": "${workspaceFolder}/../tools/cross/bin/i386-elf-gcc",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++20",
|
||||
"intelliSenseMode": "gcc-x86",
|
||||
"configurationProvider": "ms-vscode.makefile-tools",
|
||||
"compilerArgs": [
|
||||
// Compiler flags
|
||||
"-fPIC",
|
||||
"-fPIE",
|
||||
"-pie",
|
||||
"-mno-80387",
|
||||
"-mno-mmx",
|
||||
"-mno-3dnow",
|
||||
"-mno-red-zone",
|
||||
"-mno-sse",
|
||||
"-mno-sse2",
|
||||
"-march=i386",
|
||||
"-pipe",
|
||||
"-ffunction-sections",
|
||||
"-msoft-float",
|
||||
"-fno-builtin",
|
||||
// C++ flags
|
||||
"-fexceptions",
|
||||
// Linker flags
|
||||
"-fPIC",
|
||||
"-fPIE",
|
||||
"-pie",
|
||||
"-Wl,-eDriverEntry",
|
||||
"-Wl,-static,--no-dynamic-linker,-ztext,--no-warn-rwx-segment",
|
||||
"-nostdlib",
|
||||
"-nodefaultlibs",
|
||||
"-nolibc",
|
||||
"-zmax-page-size=0x1000",
|
||||
"-static",
|
||||
// VSCode flags
|
||||
"-ffreestanding",
|
||||
"-nostdinc",
|
||||
"-nostdinc++"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Fennix Aarch64 (Linux, GCC, debug)",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/include",
|
||||
"${workspaceFolder}/include/**"
|
||||
],
|
||||
"defines": [
|
||||
"__debug_vscode__",
|
||||
"KERNEL_NAME=\"Fennix\"",
|
||||
"KERNEL_VERSION=\"1.0\"",
|
||||
"GIT_COMMIT=\"0000000000000000000000000000000000000000\"",
|
||||
"GIT_COMMIT_SHORT=\"0000000\"",
|
||||
"DEBUG=\"1\""
|
||||
],
|
||||
"compilerPath": "${workspaceFolder}/../tools/cross/bin/aarch64-fennix-gcc",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++20",
|
||||
"intelliSenseMode": "linux-gcc-arm64",
|
||||
"configurationProvider": "ms-vscode.makefile-tools",
|
||||
"compilerArgs": [
|
||||
"-ffreestanding",
|
||||
"-nostdinc",
|
||||
"-nostdinc++"
|
||||
]
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
1
Drivers/.vscode/launch.json
vendored
Symbolic link
1
Drivers/.vscode/launch.json
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../../.vscode/launch.json
|
1
Drivers/.vscode/tasks.json
vendored
Symbolic link
1
Drivers/.vscode/tasks.json
vendored
Symbolic link
@ -0,0 +1 @@
|
||||
../../.vscode/tasks.json
|
2659
Drivers/Doxyfile
2659
Drivers/Doxyfile
File diff suppressed because it is too large
Load Diff
@ -1,29 +0,0 @@
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2022, EnderIce2
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@ -1,23 +1,89 @@
|
||||
default:
|
||||
$(error Do not run this Makefile directly!)
|
||||
|
||||
export CC := $(__CONF_CC)
|
||||
export CXX := $(__CONF_CXX)
|
||||
export LD := $(__CONF_LD)
|
||||
export AS := $(__CONF_AS)
|
||||
export OBJDUMP := $(__CONF_OBJDUMP)
|
||||
|
||||
export OUTPUT_DIR := $(CURDIR)/out/
|
||||
export INCLUDE_DIR := $(CURDIR)/include
|
||||
|
||||
DRIVER_LDFLAGS = -nostdlib -nodefaultlibs -nolibc -zmax-page-size=0x1000 \
|
||||
-Wl,-Map file.map -fvisibility=hidden -Wl,--dynamic-linker=/boot/fennix.elf
|
||||
|
||||
ifeq ($(OSARCH), amd64)
|
||||
DRIVER_CFLAGS = -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
||||
-mno-red-zone -mno-sse -mno-sse2 \
|
||||
-march=x86-64 -pipe -ffunction-sections \
|
||||
-msoft-float -fno-builtin
|
||||
|
||||
else ifeq ($(OSARCH), i386)
|
||||
DRIVER_CFLAGS = -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
||||
-mno-red-zone -mno-sse -mno-sse2 -ffunction-sections \
|
||||
-march=i386 -pipe -msoft-float -fno-builtin
|
||||
else ifeq ($(OSARCH), aarch64)
|
||||
DRIVER_CFLAGS = -pipe -fno-builtin -fPIC
|
||||
endif
|
||||
|
||||
DRIVER_CFLAGS += -I$(CURDIR)/include
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
DRIVER_CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage
|
||||
ifeq ($(OSARCH), amd64)
|
||||
DRIVER_CFLAGS += -fverbose-asm
|
||||
endif
|
||||
ifneq ($(OSARCH), aarch64)
|
||||
DRIVER_CFLAGS += -fstack-check
|
||||
endif
|
||||
DRIVER_LDFLAGS += -ggdb3 -O0
|
||||
endif
|
||||
|
||||
export DRIVER_LDFLAGS
|
||||
export DRIVER_CFLAGS
|
||||
|
||||
copy_driver_signatures:
|
||||
@TMP_FILE="$(OUTPUT_DIR)../../Kernel/drivers/trusted.c.tmp"; \
|
||||
OUT_FILE="$(OUTPUT_DIR)../../Kernel/drivers/trusted.c"; \
|
||||
mkdir -p $(OUTPUT_DIR)../../Kernel/drivers/; \
|
||||
echo "const char *trusted_drivers[] = {" > $$TMP_FILE; \
|
||||
find $(OUTPUT_DIR) -name "*.drv" -exec sha512sum {} \; | awk '{gsub(/.*\//, "", $$2); gsub(/\./, "_", $$2); sub(/_drv$$/, "_drv", $$2); print "\"" $$1 "\"," }' >> $$TMP_FILE; \
|
||||
echo "};" >> $$TMP_FILE; \
|
||||
echo "const __SIZE_TYPE__ trusted_drivers_count = sizeof(trusted_drivers) / sizeof(trusted_drivers[0]);" >> $$TMP_FILE; \
|
||||
if [ ! -f $$OUT_FILE ] || ! cmp -s $$TMP_FILE $$OUT_FILE; then \
|
||||
mv $$TMP_FILE $$OUT_FILE; \
|
||||
printf '\033[0;32m[trusted.c updated]\033[0m\n'; \
|
||||
else \
|
||||
rm $$TMP_FILE; \
|
||||
printf '\033[0;33m[trusted.c unchanged]\033[0m\n'; \
|
||||
fi
|
||||
|
||||
build:
|
||||
cp -rf ../Kernel/include/interface/* include/
|
||||
mkdir -p out
|
||||
make -C library build
|
||||
make -C audio build
|
||||
make -C input build
|
||||
make -C misc build
|
||||
make -C network build
|
||||
make -C storage build
|
||||
make -C filesystem build
|
||||
$(MAKE) -C library build
|
||||
ifneq ($(filter amd64 i386,$(OSARCH)),)
|
||||
$(MAKE) -C audio build
|
||||
$(MAKE) -C input build
|
||||
$(MAKE) -C misc build
|
||||
$(MAKE) -C network build
|
||||
$(MAKE) -C storage build
|
||||
$(MAKE) -C filesystem build
|
||||
endif
|
||||
$(MAKE) copy_driver_signatures
|
||||
|
||||
prepare:
|
||||
$(info Nothing to prepare)
|
||||
|
||||
clean:
|
||||
rm -rf out
|
||||
make -C library clean
|
||||
make -C audio clean
|
||||
make -C input clean
|
||||
make -C misc clean
|
||||
make -C network clean
|
||||
make -C storage clean
|
||||
make -C filesystem clean
|
||||
$(MAKE) -C library clean
|
||||
ifneq ($(filter amd64 i386,$(OSARCH)),)
|
||||
$(MAKE) -C audio clean
|
||||
$(MAKE) -C input clean
|
||||
$(MAKE) -C misc clean
|
||||
$(MAKE) -C network clean
|
||||
$(MAKE) -C storage clean
|
||||
$(MAKE) -C filesystem clean
|
||||
endif
|
||||
|
@ -1,11 +1 @@
|
||||
# Drivers
|
||||
|
||||
Drivers for [Fennix](https://github.com/Fennix-Project/Fennix).
|
||||
|
||||
---
|
||||
|
||||
Use `Fennix` repo to build the operating system.
|
||||
|
||||
```bash
|
||||
git clone --recurse-submodules https://github.com/Fennix-Project/Fennix.git
|
||||
```
|
||||
|
@ -1,7 +1,9 @@
|
||||
build:
|
||||
make -C ac97 build
|
||||
make -C hda build
|
||||
MAKE_TARGETS := build clean
|
||||
DIRECTORIES := $(sort $(dir $(wildcard ./*/)))
|
||||
|
||||
clean:
|
||||
make -C ac97 clean
|
||||
make -C hda clean
|
||||
.PHONY: $(MAKE_TARGETS) $(DIRECTORIES)
|
||||
|
||||
$(MAKE_TARGETS): $(DIRECTORIES)
|
||||
|
||||
$(DIRECTORIES):
|
||||
$(MAKE) -C $@ $(MAKECMDGOALS)
|
||||
|
@ -1,22 +0,0 @@
|
||||
# Config files
|
||||
include ../../../Makefile.conf
|
||||
include ../../config.mk
|
||||
|
||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
||||
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
|
||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||
|
||||
FILENAME = ac97.drv
|
||||
|
||||
build: $(FILENAME)
|
||||
mv $(FILENAME) ../../out/$(FILENAME)
|
||||
|
||||
$(FILENAME): $(OBJ)
|
||||
$(info Linking $@)
|
||||
$(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@
|
||||
|
||||
clean:
|
||||
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
@ -1,881 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <audio.h>
|
||||
#include <regs.h>
|
||||
#include <base.h>
|
||||
#include <pci.h>
|
||||
#include <io.h>
|
||||
#include <fs.h>
|
||||
|
||||
#define DescriptorListLength 0x20
|
||||
|
||||
enum AudioVolumeValues
|
||||
{
|
||||
AV_Maximum = 0x0,
|
||||
AV_Minimum = 0x3F,
|
||||
};
|
||||
|
||||
enum AudioEncodingValues
|
||||
{
|
||||
AE_PCMs8,
|
||||
AE_PCMu8,
|
||||
|
||||
AE_PCMs16le,
|
||||
AE_PCMs20le,
|
||||
AE_PCMs24le,
|
||||
AE_PCMs32le,
|
||||
|
||||
AE_PCMu16le,
|
||||
AE_PCMu20le,
|
||||
AE_PCMu24le,
|
||||
AE_PCMu32le,
|
||||
|
||||
AE_PCMs16be,
|
||||
AE_PCMs20be,
|
||||
AE_PCMs24be,
|
||||
AE_PCMs32be,
|
||||
|
||||
AE_PCMu16be,
|
||||
AE_PCMu20be,
|
||||
AE_PCMu24be,
|
||||
AE_PCMu32be,
|
||||
};
|
||||
|
||||
enum NativeAudioMixerRegisters
|
||||
{
|
||||
/**
|
||||
* @brief Reset Register
|
||||
* @note Length: word
|
||||
*/
|
||||
NAM_Reset = 0x00,
|
||||
|
||||
/**
|
||||
* @brief Master Volume Register
|
||||
* @note Length: word
|
||||
*/
|
||||
NAM_MasterVolume = 0x02,
|
||||
|
||||
/**
|
||||
* @brief Microphone Volume Register
|
||||
* @note Length: word
|
||||
*/
|
||||
NAM_MicrophoneVolume = 0x0E,
|
||||
|
||||
/**
|
||||
* @brief PCM Out Volume Register
|
||||
* @note Length: word
|
||||
*/
|
||||
NAM_PCMOutVolume = 0x18,
|
||||
|
||||
/**
|
||||
* @brief Select Record Input Register
|
||||
* @note Length: word
|
||||
*/
|
||||
NAM_SelectRecordInput = 0x1A,
|
||||
|
||||
/**
|
||||
* @brief Record Gain Register
|
||||
* @note Length: word
|
||||
*/
|
||||
NAM_RecordGain = 0x1C,
|
||||
|
||||
/**
|
||||
* @brief Record Gain Microphone Register
|
||||
* @note Length: word
|
||||
*/
|
||||
NAM_RecordGainMicrophone = 0x1E,
|
||||
};
|
||||
|
||||
enum NativeAudioBusMasterRegisters
|
||||
{
|
||||
/**
|
||||
* @brief Register box for PCM IN
|
||||
* @note Length: below
|
||||
*/
|
||||
NABM_PCMInBox = 0x00,
|
||||
|
||||
/**
|
||||
* @brief Register box for PCM OUT
|
||||
* @note Length: below
|
||||
*/
|
||||
NABM_PCMOutBox = 0x10,
|
||||
|
||||
/**
|
||||
* @brief Register box for Microphone
|
||||
* @note Length: below
|
||||
*/
|
||||
NABM_MicrophoneBox = 0x20,
|
||||
|
||||
/**
|
||||
* @brief Global Control Register
|
||||
* @note Length: dword
|
||||
*/
|
||||
NABM_GlobalControl = 0x2C, /* 0x30 */
|
||||
|
||||
/**
|
||||
* @brief Global Status Register
|
||||
* @note Length: dword
|
||||
*/
|
||||
NABM_GlobalStatus = 0x30, /* 0x34 */
|
||||
};
|
||||
|
||||
enum NativeAudioBusMasterBoxOffsets
|
||||
{
|
||||
/**
|
||||
* @brief Physical Address of Buffer Descriptor List
|
||||
* @note Length: dword
|
||||
*/
|
||||
NABMBOFF_BufferDescriptorList = 0x00,
|
||||
|
||||
/**
|
||||
* @brief Number of Actual Processed Buffer Descriptor Entry
|
||||
* @note Length: byte
|
||||
*/
|
||||
NABMBOFF_BufferDescriptorEntry = 0x04,
|
||||
|
||||
/**
|
||||
* @brief Number of all Descriptor Entries
|
||||
* @note Length: byte
|
||||
*/
|
||||
NABMBOFF_DescriptorEntries = 0x05,
|
||||
|
||||
/**
|
||||
* @brief Status of transferring Data
|
||||
* @note Length: word
|
||||
*/
|
||||
NABMBOFF_Status = 0x06,
|
||||
|
||||
/**
|
||||
* @brief Number of transferred Samples in Actual Processed Entry
|
||||
* @note Length: word
|
||||
*/
|
||||
NABMBOFF_TransferredSamples = 0x08,
|
||||
|
||||
/**
|
||||
* @brief Number of next processed Buffer Entry
|
||||
* @note Length: byte
|
||||
*/
|
||||
NABMBOFF_NextProcessedBufferEntry = 0x0A,
|
||||
|
||||
/**
|
||||
* @brief Transfer Control
|
||||
* @note Length: byte
|
||||
*/
|
||||
NABMBOFF_TransferControl = 0x0B,
|
||||
};
|
||||
|
||||
enum OutputPulseCodeModulationRegisters
|
||||
{
|
||||
/**
|
||||
* @brief Physical Address of Buffer Descriptor List
|
||||
* @note Length: dword
|
||||
*/
|
||||
PCMOUT_BufferDescriptorList = (int)NABM_PCMOutBox + (int)NABMBOFF_BufferDescriptorList,
|
||||
|
||||
/**
|
||||
* @brief Number of Actual Processed Buffer Descriptor Entry
|
||||
* @note Length: byte
|
||||
*/
|
||||
PCMOUT_BufferDescriptorEntry = (int)NABM_PCMOutBox + (int)NABMBOFF_BufferDescriptorEntry,
|
||||
|
||||
/**
|
||||
* @brief Number of all Descriptor Entries
|
||||
* @note Length: byte
|
||||
*/
|
||||
PCMOUT_DescriptorEntries = (int)NABM_PCMOutBox + (int)NABMBOFF_DescriptorEntries,
|
||||
|
||||
/**
|
||||
* @brief Status of transferring Data
|
||||
* @note Length: word
|
||||
*/
|
||||
PCMOUT_Status = (int)NABM_PCMOutBox + (int)NABMBOFF_Status,
|
||||
|
||||
/**
|
||||
* @brief Number of transferred Samples in Actual Processed Entry
|
||||
* @note Length: word
|
||||
*/
|
||||
PCMOUT_TransferredSamples = (int)NABM_PCMOutBox + (int)NABMBOFF_TransferredSamples,
|
||||
|
||||
/**
|
||||
* @brief Number of next processed Buffer Entry
|
||||
* @note Length: byte
|
||||
*/
|
||||
PCMOUT_NextProcessedBufferEntry = (int)NABM_PCMOutBox + (int)NABMBOFF_NextProcessedBufferEntry,
|
||||
|
||||
/**
|
||||
* @brief Transfer Control
|
||||
* @note Length: byte
|
||||
*/
|
||||
PCMOUT_TransferControl = (int)NABM_PCMOutBox + (int)NABMBOFF_TransferControl,
|
||||
};
|
||||
|
||||
enum TransferControlRegisters
|
||||
{
|
||||
/**
|
||||
* @brief DMA controller control
|
||||
*
|
||||
* 0 = Pause transfer
|
||||
* 1 = Transfer sound data
|
||||
*/
|
||||
TC_DMAControllerControl = 0x01,
|
||||
|
||||
/**
|
||||
* @brief Reset
|
||||
*
|
||||
* 0 = Remove reset condition
|
||||
* 1 = Reset this NABM register box, this bit is cleared by card when is reset complete
|
||||
*/
|
||||
TC_TransferReset = 0x02,
|
||||
|
||||
/**
|
||||
* @brief Last Buffer Entry Interrupt enable
|
||||
*
|
||||
* 0 = Disable interrupt
|
||||
* 1 = Enable interrupt
|
||||
*/
|
||||
TC_LastBufferEntryInterruptEnable = 0x04,
|
||||
|
||||
/**
|
||||
* @brief IOC Interrupt enable
|
||||
*
|
||||
* 0 = Disable interrupt
|
||||
* 1 = Enable interrupt
|
||||
*/
|
||||
TC_IOCInterruptEnable = 0x08,
|
||||
|
||||
/**
|
||||
* @brief Fifo ERROR Interrupt enable
|
||||
*
|
||||
* 0 = Disable interrupt
|
||||
* 1 = Enable interrupt
|
||||
*/
|
||||
TC_FifoERRORInterruptEnable = 0x10,
|
||||
};
|
||||
|
||||
enum GlobalControlRegisters
|
||||
{
|
||||
/**
|
||||
* @brief Global Interrupt Enable
|
||||
*
|
||||
* 0 = Disable Interrupts
|
||||
* 1 = Enable Interrupts
|
||||
*/
|
||||
GC_GlobalInterruptEnable = 0x01,
|
||||
|
||||
/**
|
||||
* @brief Cold reset
|
||||
*
|
||||
* 0 = Device is in reset and can not be used
|
||||
* 1 = Resume to operational state
|
||||
*/
|
||||
GC_ColdReset = 0x02,
|
||||
|
||||
/**
|
||||
* @brief Warm reset
|
||||
*/
|
||||
GC_WarmReset = 0x04,
|
||||
|
||||
/**
|
||||
* @brief Shut down
|
||||
*
|
||||
* 0 = Device is powered
|
||||
* 1 = Shut down
|
||||
*/
|
||||
GC_ShutDown = 0x08,
|
||||
|
||||
/**
|
||||
* @brief Channels for PCM Output
|
||||
*
|
||||
* 00 = 2 channels
|
||||
* 01 = 4 channels
|
||||
* 10 = 6 channels
|
||||
* 11 = Reserved
|
||||
*/
|
||||
GC_ChannelsForPCMOutput = 0x30,
|
||||
|
||||
/**
|
||||
* @brief PCM Output mode
|
||||
*
|
||||
* 00 = 16 bit samples
|
||||
* 01 = 20 bit samples
|
||||
*/
|
||||
GC_PCMOutputMode = 0xC0,
|
||||
};
|
||||
|
||||
struct BufferDescriptorList
|
||||
{
|
||||
/**
|
||||
* @brief Physical Address to sound data in memory
|
||||
* @note Length: dword
|
||||
*/
|
||||
uint32_t Address;
|
||||
|
||||
/**
|
||||
* @brief Number of samples in this buffer
|
||||
* @note Length: word
|
||||
*/
|
||||
uint16_t SampleCount;
|
||||
|
||||
/**
|
||||
* @brief Flags
|
||||
* @note Length: word
|
||||
*
|
||||
* Bit 15 = Interrupt fired when data from this entry is transferred
|
||||
* Bit 14 = Last entry of buffer, stop playing
|
||||
* Other bits = Reserved
|
||||
*/
|
||||
uint16_t Flags;
|
||||
} __attribute__((packed));
|
||||
|
||||
uint16_t MixerVolume(uint8_t Left, uint8_t Right, bool Mute)
|
||||
{
|
||||
return ((uint16_t)((Right & 0x3F) |
|
||||
((Left & 0x3F) << 0x8) |
|
||||
(Mute & 1 << 0xF)));
|
||||
}
|
||||
|
||||
class AC97Device
|
||||
{
|
||||
private:
|
||||
PCIHeader0 *Header;
|
||||
BufferDescriptorList *DescriptorList = nullptr;
|
||||
|
||||
uint16_t MixerAddress;
|
||||
uint16_t BusMasterAddress;
|
||||
|
||||
AudioEncodingValues Encoding = AE_PCMs16le;
|
||||
char Channels = 2;
|
||||
uint8_t Volume = AV_Maximum;
|
||||
bool Mute = false;
|
||||
int SampleRate = 48000;
|
||||
char SampleSize = 2;
|
||||
|
||||
public:
|
||||
size_t write(uint8_t *Buffer, size_t Size)
|
||||
{
|
||||
if (Buffer == nullptr)
|
||||
{
|
||||
KernelLog("Invalid buffer.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((Size == 0) || (Size % (SampleSize * Channels)))
|
||||
{
|
||||
KernelLog("Invalid buffer length.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int TotalBDLToFill = (int)((Size + PAGE_SIZE - 1) >> 12);
|
||||
|
||||
while (Size > 0)
|
||||
{
|
||||
bool ActiveDMA = !(inw(BusMasterAddress + PCMOUT_Status) & TC_DMAControllerControl);
|
||||
|
||||
if (ActiveDMA)
|
||||
{
|
||||
int RemainingBDL = 0;
|
||||
|
||||
do
|
||||
{
|
||||
int CurrentBDL = inb(BusMasterAddress + PCMOUT_BufferDescriptorEntry);
|
||||
int LastBDL = inb(BusMasterAddress + PCMOUT_DescriptorEntries);
|
||||
|
||||
RemainingBDL = LastBDL - CurrentBDL;
|
||||
if (RemainingBDL < 0)
|
||||
RemainingBDL += DescriptorListLength;
|
||||
|
||||
RemainingBDL += 1;
|
||||
|
||||
if (RemainingBDL >= DescriptorListLength - 1)
|
||||
{
|
||||
long SampleCount = DescriptorList[(CurrentBDL + 1) % DescriptorListLength].SampleCount / Channels;
|
||||
if (SampleCount > 0)
|
||||
Sleep(SampleCount * 1000 / SampleRate);
|
||||
}
|
||||
|
||||
} while (RemainingBDL >= DescriptorListLength - 1 &&
|
||||
!(inw(BusMasterAddress + PCMOUT_Status) & TC_DMAControllerControl));
|
||||
}
|
||||
|
||||
uint8_t CurrentBDL = inb(BusMasterAddress + PCMOUT_BufferDescriptorEntry);
|
||||
uint8_t LastBDL = inb(BusMasterAddress + PCMOUT_DescriptorEntries);
|
||||
uint8_t NextBDL = LastBDL % DescriptorListLength;
|
||||
|
||||
ActiveDMA = !(inw(BusMasterAddress + PCMOUT_Status) & TC_DMAControllerControl);
|
||||
if (ActiveDMA)
|
||||
{
|
||||
NextBDL = (uint8_t)((LastBDL + 1) % DescriptorListLength);
|
||||
if (NextBDL == CurrentBDL)
|
||||
continue;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
size_t Wrote = (PAGE_SIZE > Size) ? size_t(Size)
|
||||
: size_t(PAGE_SIZE);
|
||||
|
||||
if (Wrote == 0)
|
||||
{
|
||||
KernelLog("Wrote 0 bytes.");
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy((void *)((uint64_t)DescriptorList[NextBDL].Address), Buffer, Wrote);
|
||||
DescriptorList[NextBDL].Flags = 0;
|
||||
|
||||
Buffer += Wrote;
|
||||
Size -= (unsigned int)Wrote;
|
||||
|
||||
DescriptorList[NextBDL].SampleCount = uint16_t(Wrote / SampleSize);
|
||||
TotalBDLToFill--;
|
||||
NextBDL = (uint8_t)((NextBDL + 1) % DescriptorListLength);
|
||||
} while (TotalBDLToFill-- && NextBDL != CurrentBDL);
|
||||
|
||||
outb(BusMasterAddress + PCMOUT_DescriptorEntries, NextBDL - 1);
|
||||
|
||||
ActiveDMA = !(inw(BusMasterAddress + PCMOUT_Status) & TC_DMAControllerControl);
|
||||
if (!ActiveDMA)
|
||||
{
|
||||
// Start DMA
|
||||
outb(BusMasterAddress + PCMOUT_TransferControl,
|
||||
inb(BusMasterAddress + PCMOUT_TransferControl) | TC_DMAControllerControl);
|
||||
}
|
||||
}
|
||||
return Size;
|
||||
}
|
||||
|
||||
int ioctl(AudioIoctl, void *)
|
||||
{
|
||||
// if (Data->AudioCallback.Adjust._Volume)
|
||||
// {
|
||||
// Volume = (uint8_t)(0x3F - (0x3F * Data->AudioCallback.Adjust.Volume / 100));
|
||||
// outw(BAR.MixerAddress + NAM_MasterVolume, MixerVolume(Volume, Volume, Mute));
|
||||
// // outw(BAR.MixerAddress + NAM_PCMOutVolume, MixerVolume(Volume, Volume, Mute));
|
||||
// }
|
||||
// else if (Data->AudioCallback.Adjust._Encoding)
|
||||
// {
|
||||
// fixme("Encoding changing not supported yet.");
|
||||
// }
|
||||
// else if (Data->AudioCallback.Adjust._SampleRate)
|
||||
// {
|
||||
// switch (Data->AudioCallback.Adjust.SampleRate)
|
||||
// {
|
||||
// case 0:
|
||||
// {
|
||||
// SampleRate = 8000;
|
||||
// break;
|
||||
// }
|
||||
// case 1:
|
||||
// {
|
||||
// SampleRate = 11025;
|
||||
// break;
|
||||
// }
|
||||
// case 2:
|
||||
// {
|
||||
// SampleRate = 16000;
|
||||
// break;
|
||||
// }
|
||||
// case 3:
|
||||
// {
|
||||
// SampleRate = 22050;
|
||||
// break;
|
||||
// }
|
||||
// case 4:
|
||||
// {
|
||||
// SampleRate = 32000;
|
||||
// break;
|
||||
// }
|
||||
// case 5:
|
||||
// {
|
||||
// SampleRate = 44100;
|
||||
// break;
|
||||
// }
|
||||
// case 6:
|
||||
// {
|
||||
// SampleRate = 48000;
|
||||
// break;
|
||||
// }
|
||||
// case 7:
|
||||
// {
|
||||
// SampleRate = 88200;
|
||||
// break;
|
||||
// }
|
||||
// case 8:
|
||||
// {
|
||||
// SampleRate = 96000;
|
||||
// break;
|
||||
// }
|
||||
// default:
|
||||
// {
|
||||
// SampleRate = 16000;
|
||||
// error("Invalid sample rate. Defaulting to 16000.");
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// else if (Data->AudioCallback.Adjust._Channels)
|
||||
// {
|
||||
// switch (Data->AudioCallback.Adjust.Channels)
|
||||
// {
|
||||
// case 0:
|
||||
// {
|
||||
// Channels = 1; // Mono
|
||||
// break;
|
||||
// }
|
||||
// case 1:
|
||||
// {
|
||||
// Channels = 2; // Stereo
|
||||
// break;
|
||||
// }
|
||||
// default:
|
||||
// {
|
||||
// Channels = 2;
|
||||
// error("Invalid channel count. Defaulting to 2.");
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
return 0;
|
||||
}
|
||||
|
||||
void OnInterruptReceived(TrapFrame *)
|
||||
{
|
||||
uint16_t Status = inw(MixerAddress + PCMOUT_Status);
|
||||
if (Status & TC_IOCInterruptEnable)
|
||||
{
|
||||
DebugLog("IOC");
|
||||
outw(MixerAddress + PCMOUT_Status, TC_IOCInterruptEnable);
|
||||
uint16_t CurrentBDL = inb(BusMasterAddress + PCMOUT_BufferDescriptorEntry);
|
||||
uint16_t LastBDL = (CurrentBDL + 2) & (DescriptorListLength - 1);
|
||||
outb(BusMasterAddress + PCMOUT_DescriptorEntries, LastBDL);
|
||||
KernelLog("FIXME: CurrentBDL: %d, LastBDL: %d", CurrentBDL, LastBDL);
|
||||
}
|
||||
else if (Status & TC_LastBufferEntryInterruptEnable)
|
||||
{
|
||||
DebugLog("Last buffer entry");
|
||||
// Stop DMA
|
||||
uint8_t TransferControl = inb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl));
|
||||
TransferControl &= ~TC_DMAControllerControl;
|
||||
outb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl), TransferControl);
|
||||
|
||||
outw(MixerAddress + PCMOUT_Status, TC_LastBufferEntryInterruptEnable);
|
||||
}
|
||||
else if (Status & TC_FifoERRORInterruptEnable)
|
||||
{
|
||||
KernelLog("FIFO error");
|
||||
outw(MixerAddress + PCMOUT_Status, TC_FifoERRORInterruptEnable);
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLog("Unknown interrupt status %#x", Status);
|
||||
outw(MixerAddress + PCMOUT_Status, 0xFFFF);
|
||||
}
|
||||
}
|
||||
|
||||
void Panic()
|
||||
{
|
||||
uint8_t TransferControl = inb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl));
|
||||
TransferControl &= ~(TC_LastBufferEntryInterruptEnable |
|
||||
TC_IOCInterruptEnable |
|
||||
TC_FifoERRORInterruptEnable);
|
||||
outb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl), TransferControl);
|
||||
|
||||
uint32_t GlobalControl = inl((uint16_t)(BusMasterAddress + NABM_GlobalControl));
|
||||
GlobalControl &= ~GC_GlobalInterruptEnable;
|
||||
GlobalControl |= GC_ShutDown;
|
||||
outl((uint16_t)(BusMasterAddress + NABM_GlobalControl), GlobalControl);
|
||||
}
|
||||
|
||||
AC97Device(PCIHeader0 *_Header)
|
||||
: Header(_Header)
|
||||
{
|
||||
/* Native Audio Mixer Base Address */
|
||||
uint32_t PCIBAR0 = Header->BAR0;
|
||||
|
||||
/* Native Audio Bus Master Base Address */
|
||||
uint32_t PCIBAR1 = Header->BAR1;
|
||||
|
||||
// uint8_t Type = PCIBAR0 & 1;
|
||||
MixerAddress = (uint16_t)(PCIBAR0 & (~3));
|
||||
BusMasterAddress = PCIBAR1 & (~15);
|
||||
|
||||
uint16_t OutputPCMTransferControl = BusMasterAddress + PCMOUT_TransferControl;
|
||||
|
||||
/* DescriptorList address MUST be physical. */
|
||||
DescriptorList = (BufferDescriptorList *)AllocateMemory(TO_PAGES(sizeof(BufferDescriptorList) * DescriptorListLength));
|
||||
memset(DescriptorList, 0, sizeof(BufferDescriptorList) * DescriptorListLength);
|
||||
|
||||
uint16_t DLSampleCount = (uint16_t)(PAGE_SIZE / SampleSize);
|
||||
for (int i = 0; i < DescriptorListLength; i++)
|
||||
{
|
||||
DescriptorList[i].Address = (uint32_t)(uintptr_t)AllocateMemory(TO_PAGES(sizeof(uint16_t *)));
|
||||
DescriptorList[i].SampleCount = DLSampleCount;
|
||||
DescriptorList[i].Flags = 0;
|
||||
DebugLog("DescriptorList[%d] = { Address: %#lx, SampleCount: %d, Flags: %#lx }",
|
||||
i,
|
||||
DescriptorList[i].Address,
|
||||
DescriptorList[i].SampleCount,
|
||||
DescriptorList[i].Flags);
|
||||
}
|
||||
|
||||
outw(MixerAddress + NAM_MasterVolume, MixerVolume(Volume, Volume, Mute));
|
||||
outw(MixerAddress + NAM_PCMOutVolume, MixerVolume(Volume, Volume, Mute));
|
||||
|
||||
Volume = 0x3F - (0x3F * /* VOL 50% */ 50 / 100);
|
||||
outw(MixerAddress + NAM_MasterVolume, MixerVolume(Volume, Volume, Mute));
|
||||
|
||||
outb(OutputPCMTransferControl, inb(OutputPCMTransferControl) | TC_TransferReset);
|
||||
while (inb(OutputPCMTransferControl) & TC_TransferReset)
|
||||
;
|
||||
|
||||
uint32_t GlobalControl = inl(BusMasterAddress + NABM_GlobalControl);
|
||||
GlobalControl = (GlobalControl & ~((0x3U) << 0x16)); /* PCM 16-bit mode */
|
||||
GlobalControl = (GlobalControl & ~((0x3U) << 20)); /* 2 channels */
|
||||
GlobalControl |= GC_GlobalInterruptEnable;
|
||||
GlobalControl &= ~GC_ShutDown;
|
||||
|
||||
outl(BusMasterAddress + PCMOUT_BufferDescriptorList,
|
||||
(uint32_t)(uint64_t)DescriptorList);
|
||||
|
||||
outl(BusMasterAddress + NABM_GlobalControl, GlobalControl);
|
||||
|
||||
uint8_t TransferControl = inb(OutputPCMTransferControl);
|
||||
TransferControl |= TC_IOCInterruptEnable |
|
||||
TC_FifoERRORInterruptEnable;
|
||||
outb(OutputPCMTransferControl, TransferControl);
|
||||
|
||||
// Stop DMA
|
||||
outb(OutputPCMTransferControl, inb(OutputPCMTransferControl) & ~TC_DMAControllerControl);
|
||||
}
|
||||
|
||||
~AC97Device()
|
||||
{
|
||||
outw(MixerAddress + NAM_MasterVolume, MixerVolume(AV_Maximum, AV_Maximum, true));
|
||||
outw(MixerAddress + NAM_PCMOutVolume, MixerVolume(AV_Maximum, AV_Maximum, true));
|
||||
|
||||
// Stop DMA
|
||||
outb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl),
|
||||
inb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl)) & ~TC_DMAControllerControl);
|
||||
|
||||
// Disable interrupts
|
||||
uint8_t TransferControl = inb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl));
|
||||
|
||||
TransferControl &= ~(TC_LastBufferEntryInterruptEnable |
|
||||
TC_IOCInterruptEnable |
|
||||
TC_FifoERRORInterruptEnable);
|
||||
outb((uint16_t)(BusMasterAddress + PCMOUT_TransferControl), TransferControl);
|
||||
|
||||
// Disable global control
|
||||
uint32_t GlobalControl = inl((uint16_t)(BusMasterAddress + NABM_GlobalControl));
|
||||
GlobalControl &= ~GC_GlobalInterruptEnable;
|
||||
GlobalControl |= GC_ShutDown;
|
||||
outl((uint16_t)(BusMasterAddress + NABM_GlobalControl), GlobalControl);
|
||||
}
|
||||
};
|
||||
|
||||
AC97Device *Drivers[4] = {nullptr};
|
||||
dev_t AudioID[4] = {(dev_t)-1};
|
||||
|
||||
#define OIR(x) OIR_##x
|
||||
#define CREATE_OIR(x) \
|
||||
void OIR_##x(TrapFrame *f) { Drivers[x]->OnInterruptReceived(f); }
|
||||
|
||||
CREATE_OIR(0);
|
||||
CREATE_OIR(1);
|
||||
CREATE_OIR(2);
|
||||
CREATE_OIR(3);
|
||||
|
||||
int __fs_Open(struct Inode *, int, mode_t) { return 0; }
|
||||
int __fs_Close(struct Inode *) { return 0; }
|
||||
ssize_t __fs_Read(struct Inode *, void *, size_t, off_t) { return 0; }
|
||||
|
||||
ssize_t __fs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t)
|
||||
{
|
||||
return Drivers[AudioID[Node->GetMinor()]]->write((uint8_t *)Buffer, Size);
|
||||
}
|
||||
|
||||
int __fs_Ioctl(struct Inode *Node, unsigned long Request, void *Argp)
|
||||
{
|
||||
return Drivers[AudioID[Node->GetMinor()]]->ioctl((AudioIoctl)Request, Argp);
|
||||
}
|
||||
|
||||
const struct InodeOperations AudioOps = {
|
||||
.Lookup = nullptr,
|
||||
.Create = nullptr,
|
||||
.Remove = nullptr,
|
||||
.Rename = nullptr,
|
||||
.Read = __fs_Read,
|
||||
.Write = __fs_Write,
|
||||
.Truncate = nullptr,
|
||||
.Open = __fs_Open,
|
||||
.Close = __fs_Close,
|
||||
.Ioctl = __fs_Ioctl,
|
||||
.ReadDir = nullptr,
|
||||
.MkDir = nullptr,
|
||||
.RmDir = nullptr,
|
||||
.SymLink = nullptr,
|
||||
.ReadLink = nullptr,
|
||||
.Seek = nullptr,
|
||||
.Stat = nullptr,
|
||||
};
|
||||
|
||||
PCIArray *Devices;
|
||||
EXTERNC int cxx_Panic()
|
||||
{
|
||||
PCIArray *ctx = Devices;
|
||||
short Count = 0;
|
||||
while (ctx != nullptr)
|
||||
{
|
||||
if (Drivers[Count] != nullptr)
|
||||
Drivers[Count]->Panic();
|
||||
Count++;
|
||||
ctx = (PCIArray *)ctx->Next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXTERNC int cxx_Probe()
|
||||
{
|
||||
uint16_t VendorIDs[] = {0x8086, PCI_END};
|
||||
uint16_t DeviceIDs[] = {0x2415, PCI_END};
|
||||
Devices = GetPCIDevices(VendorIDs, DeviceIDs);
|
||||
if (Devices == nullptr)
|
||||
{
|
||||
KernelLog("No AC'97 device found.");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
PCIArray *ctx = Devices;
|
||||
bool Found = false;
|
||||
size_t Count = 0;
|
||||
while (ctx != nullptr)
|
||||
{
|
||||
if (Count++ > sizeof(Drivers) / sizeof(AC97Device *))
|
||||
break;
|
||||
|
||||
PCIHeader0 *PCIBaseAddress = (PCIHeader0 *)ctx->Device->Header;
|
||||
uint32_t PCIBAR0 = PCIBaseAddress->BAR0;
|
||||
uint8_t Type = PCIBAR0 & 1;
|
||||
if (Type != 1)
|
||||
{
|
||||
KernelLog("Device %x:%x.%d BAR0 is not I/O.",
|
||||
PCIBaseAddress->Header.VendorID,
|
||||
PCIBaseAddress->Header.DeviceID,
|
||||
PCIBaseAddress->Header.ProgIF);
|
||||
continue;
|
||||
}
|
||||
|
||||
Found = true;
|
||||
ctx = (PCIArray *)ctx->Next;
|
||||
}
|
||||
|
||||
if (!Found)
|
||||
{
|
||||
KernelLog("No valid AC'97 device found.");
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXTERNC int cxx_Initialize()
|
||||
{
|
||||
PCIArray *ctx = Devices;
|
||||
size_t Count = 0;
|
||||
while (ctx != nullptr)
|
||||
{
|
||||
if (Count > sizeof(Drivers) / sizeof(AC97Device *))
|
||||
break;
|
||||
|
||||
PCIHeader0 *PCIBaseAddress = (PCIHeader0 *)ctx->Device->Header;
|
||||
uint32_t PCIBAR0 = PCIBaseAddress->BAR0;
|
||||
uint8_t Type = PCIBAR0 & 1;
|
||||
if (Type != 1)
|
||||
{
|
||||
KernelLog("Device %x:%x.%d BAR0 is not I/O.",
|
||||
PCIBaseAddress->Header.VendorID,
|
||||
PCIBaseAddress->Header.DeviceID,
|
||||
PCIBaseAddress->Header.ProgIF);
|
||||
continue;
|
||||
}
|
||||
|
||||
InitializePCI(ctx->Device);
|
||||
|
||||
Drivers[Count] = new AC97Device((PCIHeader0 *)ctx->Device->Header);
|
||||
/* FIXME: bad code */
|
||||
switch (Count)
|
||||
{
|
||||
case 0:
|
||||
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(0));
|
||||
break;
|
||||
case 1:
|
||||
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(1));
|
||||
break;
|
||||
case 2:
|
||||
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(2));
|
||||
break;
|
||||
case 3:
|
||||
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(3));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
dev_t ret = RegisterDevice(AUDIO_TYPE_PCM, &AudioOps);
|
||||
AudioID[Count] = ret;
|
||||
Count++;
|
||||
ctx = (PCIArray *)ctx->Next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXTERNC int cxx_Finalize()
|
||||
{
|
||||
PCIArray *ctx = Devices;
|
||||
size_t Count = 0;
|
||||
while (ctx != nullptr)
|
||||
{
|
||||
if (Count++ > sizeof(Drivers) / sizeof(AC97Device *))
|
||||
break;
|
||||
|
||||
PCIHeader0 *PCIBaseAddress = (PCIHeader0 *)ctx->Device->Header;
|
||||
uint32_t PCIBAR0 = PCIBaseAddress->BAR0;
|
||||
uint8_t Type = PCIBAR0 & 1;
|
||||
if (Type != 1)
|
||||
{
|
||||
KernelLog("Device %x:%x.%d BAR0 is not I/O.",
|
||||
PCIBaseAddress->Header.VendorID,
|
||||
PCIBaseAddress->Header.DeviceID,
|
||||
PCIBaseAddress->Header.ProgIF);
|
||||
continue;
|
||||
}
|
||||
|
||||
delete Drivers[Count++];
|
||||
ctx->Device->Header->Command |= PCI_COMMAND_INTX_DISABLE;
|
||||
ctx = (PCIArray *)ctx->Next;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sizeof(AudioID) / sizeof(dev_t); i++)
|
||||
{
|
||||
if (AudioID[i] != (dev_t)-1)
|
||||
UnregisterDevice(AudioID[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <base.h>
|
||||
|
||||
#include "ac97.hpp"
|
||||
|
||||
int DriverEntry() { return cxx_Initialize(); }
|
||||
int DriverFinal() { return cxx_Finalize(); }
|
||||
int DriverPanic() { return cxx_Panic(); }
|
||||
int DriverProbe() { return cxx_Probe(); }
|
||||
|
||||
DriverInfo("ac97",
|
||||
"Audio Codec '97 Driver",
|
||||
"EnderIce2",
|
||||
0, 0, 1,
|
||||
"GPLv3");
|
@ -1,22 +0,0 @@
|
||||
# Config files
|
||||
include ../../../Makefile.conf
|
||||
include ../../config.mk
|
||||
|
||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
||||
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
|
||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||
|
||||
FILENAME = hda.drv
|
||||
|
||||
build: $(FILENAME)
|
||||
mv $(FILENAME) ../../out/$(FILENAME)
|
||||
|
||||
$(FILENAME): $(OBJ)
|
||||
$(info Linking $@)
|
||||
$(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@
|
||||
|
||||
clean:
|
||||
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
@ -1,263 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <audio.h>
|
||||
#include <regs.h>
|
||||
#include <base.h>
|
||||
#include <pci.h>
|
||||
#include <io.h>
|
||||
#include <fs.h>
|
||||
|
||||
#include "hda.hpp"
|
||||
|
||||
class HDADevice
|
||||
{
|
||||
private:
|
||||
PCIHeader0 *Header;
|
||||
bool Initialized = false;
|
||||
|
||||
ControllerRegisters *CTL;
|
||||
|
||||
uint32_t *CORB;
|
||||
uint64_t *RIRB;
|
||||
|
||||
public:
|
||||
bool IsInitialized() { return Initialized; }
|
||||
|
||||
size_t write(uint8_t *, size_t Size)
|
||||
{
|
||||
return Size;
|
||||
}
|
||||
|
||||
int ioctl(AudioIoctl, void *)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void OnInterruptReceived(TrapFrame *)
|
||||
{
|
||||
}
|
||||
|
||||
void Panic()
|
||||
{
|
||||
}
|
||||
|
||||
HDADevice(PCIHeader0 *_Header)
|
||||
: Header(_Header),
|
||||
CORB((uint32_t *)(uintptr_t)AllocateMemory(1)),
|
||||
RIRB((uint64_t *)AllocateMemory(1))
|
||||
{
|
||||
CTL = (ControllerRegisters *)(uintptr_t)Header->BAR0;
|
||||
KernelLog("Unimplemented HDA driver");
|
||||
return;
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
~HDADevice()
|
||||
{
|
||||
if (!Initialized)
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
HDADevice *Drivers[4] = {nullptr};
|
||||
dev_t AudioID[4] = {(dev_t)-1};
|
||||
|
||||
#define OIR(x) OIR_##x
|
||||
#define CREATE_OIR(x) \
|
||||
void OIR_##x(TrapFrame *f) { Drivers[x]->OnInterruptReceived(f); }
|
||||
|
||||
CREATE_OIR(0);
|
||||
CREATE_OIR(1);
|
||||
CREATE_OIR(2);
|
||||
CREATE_OIR(3);
|
||||
|
||||
int __fs_Open(struct Inode *, int, mode_t) { return 0; }
|
||||
int __fs_Close(struct Inode *) { return 0; }
|
||||
ssize_t __fs_Read(struct Inode *, void *, size_t, off_t) { return 0; }
|
||||
|
||||
ssize_t __fs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t)
|
||||
{
|
||||
return Drivers[AudioID[Node->GetMinor()]]->write((uint8_t *)Buffer, Size);
|
||||
}
|
||||
|
||||
int __fs_Ioctl(struct Inode *Node, unsigned long Request, void *Argp)
|
||||
{
|
||||
return Drivers[AudioID[Node->GetMinor()]]->ioctl((AudioIoctl)Request, Argp);
|
||||
}
|
||||
|
||||
const struct InodeOperations AudioOps = {
|
||||
.Lookup = nullptr,
|
||||
.Create = nullptr,
|
||||
.Remove = nullptr,
|
||||
.Rename = nullptr,
|
||||
.Read = __fs_Read,
|
||||
.Write = __fs_Write,
|
||||
.Truncate = nullptr,
|
||||
.Open = __fs_Open,
|
||||
.Close = __fs_Close,
|
||||
.Ioctl = __fs_Ioctl,
|
||||
.ReadDir = nullptr,
|
||||
.MkDir = nullptr,
|
||||
.RmDir = nullptr,
|
||||
.SymLink = nullptr,
|
||||
.ReadLink = nullptr,
|
||||
.Seek = nullptr,
|
||||
.Stat = nullptr,
|
||||
};
|
||||
|
||||
PCIArray *Devices;
|
||||
EXTERNC int cxx_Panic()
|
||||
{
|
||||
PCIArray *ctx = Devices;
|
||||
short Count = 0;
|
||||
while (ctx != nullptr)
|
||||
{
|
||||
if (Drivers[Count] != nullptr)
|
||||
Drivers[Count]->Panic();
|
||||
Count++;
|
||||
ctx = (PCIArray *)ctx->Next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXTERNC int cxx_Probe()
|
||||
{
|
||||
uint16_t VendorIDs[] = {0x8086, /* Intel */
|
||||
0x15AD, /* VMware */
|
||||
PCI_END};
|
||||
uint16_t DeviceIDs[] = {0x9D71 /* Sunrise Point-LP HD Audio */,
|
||||
0x2668 /* ICH6 */,
|
||||
0x293E /* ICH9 */,
|
||||
PCI_END};
|
||||
Devices = GetPCIDevices(VendorIDs, DeviceIDs);
|
||||
if (Devices == nullptr)
|
||||
{
|
||||
KernelLog("No HDA device found.");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
PCIArray *ctx = Devices;
|
||||
bool Found = false;
|
||||
size_t Count = 0;
|
||||
while (ctx != nullptr)
|
||||
{
|
||||
if (Count++ > sizeof(Drivers) / sizeof(HDADevice *))
|
||||
break;
|
||||
|
||||
PCIHeader0 *PCIBaseAddress = (PCIHeader0 *)ctx->Device->Header;
|
||||
uint32_t PCIBAR0 = PCIBaseAddress->BAR0;
|
||||
uint8_t Type = PCIBAR0 & 1;
|
||||
if (Type == 1)
|
||||
{
|
||||
KernelLog("Device %x:%x.%d BAR0 is I/O.",
|
||||
PCIBaseAddress->Header.VendorID,
|
||||
PCIBaseAddress->Header.DeviceID,
|
||||
PCIBaseAddress->Header.ProgIF);
|
||||
continue;
|
||||
}
|
||||
|
||||
Found = true;
|
||||
ctx = (PCIArray *)ctx->Next;
|
||||
}
|
||||
|
||||
if (!Found)
|
||||
{
|
||||
KernelLog("No valid HDA device found.");
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXTERNC int cxx_Initialize()
|
||||
{
|
||||
PCIArray *ctx = Devices;
|
||||
size_t Count = 0;
|
||||
while (ctx != nullptr)
|
||||
{
|
||||
if (Count > sizeof(Drivers) / sizeof(HDADevice *))
|
||||
break;
|
||||
|
||||
PCIHeader0 *PCIBaseAddress = (PCIHeader0 *)ctx->Device->Header;
|
||||
uint32_t PCIBAR0 = PCIBaseAddress->BAR0;
|
||||
uint8_t Type = PCIBAR0 & 1;
|
||||
if (Type == 1)
|
||||
{
|
||||
KernelLog("Device %x:%x.%d BAR0 is I/O.",
|
||||
PCIBaseAddress->Header.VendorID,
|
||||
PCIBaseAddress->Header.DeviceID,
|
||||
PCIBaseAddress->Header.ProgIF);
|
||||
continue;
|
||||
}
|
||||
|
||||
InitializePCI(ctx->Device);
|
||||
|
||||
Drivers[Count] = new HDADevice((PCIHeader0 *)ctx->Device->Header);
|
||||
|
||||
if (Drivers[Count]->IsInitialized())
|
||||
{
|
||||
dev_t ret = RegisterDevice(AUDIO_TYPE_PCM, &AudioOps);
|
||||
AudioID[Count] = ret;
|
||||
Count++;
|
||||
}
|
||||
ctx = (PCIArray *)ctx->Next;
|
||||
}
|
||||
|
||||
if (Count == 0)
|
||||
{
|
||||
KernelLog("No valid HDA device found.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXTERNC int cxx_Finalize()
|
||||
{
|
||||
PCIArray *ctx = Devices;
|
||||
size_t Count = 0;
|
||||
while (ctx != nullptr)
|
||||
{
|
||||
if (Count++ > sizeof(Drivers) / sizeof(HDADevice *))
|
||||
break;
|
||||
|
||||
PCIHeader0 *PCIBaseAddress = (PCIHeader0 *)ctx->Device->Header;
|
||||
uint32_t PCIBAR0 = PCIBaseAddress->BAR0;
|
||||
uint8_t Type = PCIBAR0 & 1;
|
||||
if (Type == 1)
|
||||
{
|
||||
KernelLog("Device %x:%x.%d BAR0 is I/O.",
|
||||
PCIBaseAddress->Header.VendorID,
|
||||
PCIBaseAddress->Header.DeviceID,
|
||||
PCIBaseAddress->Header.ProgIF);
|
||||
continue;
|
||||
}
|
||||
|
||||
delete Drivers[Count++];
|
||||
ctx = (PCIArray *)ctx->Next;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sizeof(AudioID) / sizeof(dev_t); i++)
|
||||
{
|
||||
if (AudioID[i] != (dev_t)-1)
|
||||
UnregisterDevice(AudioID[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <base.h>
|
||||
|
||||
#include "hda.hpp"
|
||||
|
||||
int DriverEntry() { return cxx_Initialize(); }
|
||||
int DriverFinal() { return cxx_Finalize(); }
|
||||
int DriverPanic() { return cxx_Panic(); }
|
||||
int DriverProbe() { return cxx_Probe(); }
|
||||
|
||||
DriverInfo("hda",
|
||||
"Intel High Definition Audio Driver",
|
||||
"EnderIce2",
|
||||
0, 0, 1,
|
||||
"GPLv3");
|
@ -1,54 +0,0 @@
|
||||
CC = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
||||
CPP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)g++
|
||||
LD = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)ld
|
||||
AS = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
|
||||
OBJDUMP = ../../../$(COMPILER_PATH)/$(COMPILER_ARCH)objdump
|
||||
|
||||
DRIVER_LDFLAGS := -nostdlib -nodefaultlibs -nolibc -zmax-page-size=0x1000 \
|
||||
-Wl,-Map file.map -fvisibility=hidden -Wl,--dynamic-linker=/boot/fennix.elf
|
||||
|
||||
ifeq ($(OSARCH), amd64)
|
||||
|
||||
DRIVER_CFLAGS := -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
||||
-mno-red-zone -mno-sse -mno-sse2 \
|
||||
-march=x86-64 -pipe -ffunction-sections \
|
||||
-msoft-float -fno-builtin
|
||||
|
||||
else ifeq ($(OSARCH), i386)
|
||||
|
||||
DRIVER_CFLAGS := -fPIC -fPIE -pie -mno-80387 -mno-mmx -mno-3dnow \
|
||||
-mno-red-zone -mno-sse -mno-sse2 -ffunction-sections \
|
||||
-march=i386 -pipe -msoft-float -fno-builtin
|
||||
|
||||
else ifeq ($(OSARCH), aarch64)
|
||||
|
||||
DRIVER_CFLAGS += -pipe -fno-builtin -fPIC
|
||||
|
||||
endif
|
||||
|
||||
DRIVER_CFLAGS += -I../../include
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
DRIVER_CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage
|
||||
ifeq ($(OSARCH), amd64)
|
||||
DRIVER_CFLAGS += -fverbose-asm
|
||||
endif
|
||||
ifneq ($(OSARCH), aarch64)
|
||||
DRIVER_CFLAGS += -fstack-check
|
||||
endif
|
||||
DRIVER_LDFLAGS += -ggdb3 -O0
|
||||
endif
|
||||
|
||||
WARNCFLAG = -Wall -Wextra
|
||||
|
||||
%.o: %.c $(HEADERS)
|
||||
$(info Compiling $<)
|
||||
$(CC) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
|
||||
|
||||
%.o: %.cpp $(HEADERS)
|
||||
$(info Compiling $<)
|
||||
$(CPP) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@
|
||||
|
||||
%.o: %.S
|
||||
$(info Compiling $<)
|
||||
$(AS) -o $@ $<
|
@ -1,5 +1,9 @@
|
||||
build:
|
||||
make -C fat build
|
||||
MAKE_TARGETS := build clean
|
||||
DIRECTORIES := $(sort $(dir $(wildcard ./*/)))
|
||||
|
||||
clean:
|
||||
make -C fat clean
|
||||
.PHONY: $(MAKE_TARGETS) $(DIRECTORIES)
|
||||
|
||||
$(MAKE_TARGETS): $(DIRECTORIES)
|
||||
|
||||
$(DIRECTORIES):
|
||||
$(MAKE) -C $@ $(MAKECMDGOALS)
|
||||
|
@ -1,22 +0,0 @@
|
||||
# Config files
|
||||
include ../../../Makefile.conf
|
||||
include ../../config.mk
|
||||
|
||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
||||
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
|
||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||
|
||||
FILENAME = fat.drv
|
||||
|
||||
build: $(FILENAME)
|
||||
mv $(FILENAME) ../../out/$(FILENAME)
|
||||
|
||||
$(FILENAME): $(OBJ)
|
||||
$(info Linking $@)
|
||||
$(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@
|
||||
|
||||
clean:
|
||||
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <base.h>
|
||||
|
||||
int DriverEntry()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DriverFinal()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DriverPanic()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DriverProbe()
|
||||
{
|
||||
/* Nothing to do */
|
||||
return 0;
|
||||
}
|
||||
|
||||
DriverInfo("fat",
|
||||
"File Allocation Table Driver",
|
||||
"EnderIce2",
|
||||
0, 0, 1,
|
||||
"GPLv3");
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_API_AIP_H__
|
||||
@ -103,6 +103,7 @@ typedef union
|
||||
uint8_t Raw;
|
||||
} PS2_OUTPUT_PORT;
|
||||
|
||||
#ifndef __kernel__
|
||||
void PIC_EOI(uint8_t IRQ);
|
||||
void IRQ_MASK(uint8_t IRQ);
|
||||
void IRQ_UNMASK(uint8_t IRQ);
|
||||
@ -114,11 +115,11 @@ uint8_t PS2ReadStatus();
|
||||
uint8_t PS2ReadAfterACK();
|
||||
void PS2ClearOutputBuffer();
|
||||
int PS2ACKTimeout();
|
||||
#endif // !__kernel__
|
||||
|
||||
#define WaitOutput PS2Wait(DriverID, true)
|
||||
#define WaitInput PS2Wait(DriverID, false)
|
||||
|
||||
|
||||
#define PS2_KBD_CMD_SET_LEDS 0xED
|
||||
#define PS2_KBD_CMD_ECHO 0xEE
|
||||
#define PS2_KBD_CMD_SCAN_CODE_SET 0xF0
|
||||
@ -189,7 +190,6 @@ typedef union
|
||||
uint8_t Raw;
|
||||
} PS2_KBD_TYPEMATIC;
|
||||
|
||||
|
||||
#define PS2_MOUSE_CMD_SET_SCALING_1_1 0xE6
|
||||
#define PS2_MOUSE_CMD_SET_SCALING_2_1 0xE7
|
||||
#define PS2_MOUSE_CMD_SET_RESOLUTION 0xE8
|
||||
|
110
Drivers/include/block.h
Normal file
110
Drivers/include/block.h
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_API_BLOCK_H__
|
||||
#define __FENNIX_API_BLOCK_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#if __has_include(<interface/fs.h>)
|
||||
#include <interface/fs.h>
|
||||
#else
|
||||
#include <fs.h>
|
||||
#endif
|
||||
|
||||
struct BlockDevice
|
||||
{
|
||||
/**
|
||||
* @brief Base name of the device.
|
||||
*
|
||||
* This name is used to identify the device in the system. It should be unique
|
||||
* across all block devices. The kernel may append a number to this name to
|
||||
* create a unique device name (e.g., "ahci0", "ahci1").
|
||||
*/
|
||||
const char *Name;
|
||||
|
||||
/**
|
||||
* @brief Total size of the device in bytes.
|
||||
*
|
||||
* This value represents the total addressable storage capacity of the device.
|
||||
* It is used for bounds checking and partitioning.
|
||||
*/
|
||||
size_t Size;
|
||||
|
||||
/**
|
||||
* @brief Size of a single block in bytes.
|
||||
*
|
||||
* All read and write operations are performed in multiples of this block size.
|
||||
* Typical values are 512 or 4096 bytes.
|
||||
*/
|
||||
uint32_t BlockSize;
|
||||
|
||||
/**
|
||||
* @brief Number of blocks in the device.
|
||||
*
|
||||
* This value is calculated as Size / BlockSize. It represents the total number
|
||||
* of addressable blocks on the device.
|
||||
*/
|
||||
size_t BlockCount;
|
||||
|
||||
/**
|
||||
* @brief Pointer to the block device operations structure.
|
||||
*
|
||||
* This structure contains function pointers for various operations that can
|
||||
* be performed on the block device, such as read, write, and ioctl.
|
||||
*
|
||||
* Yea, inode operations are used for block devices too.
|
||||
*/
|
||||
const InodeOperations *Ops;
|
||||
|
||||
/**
|
||||
* @brief Opaque pointer to driver-specific or hardware-specific data.
|
||||
*
|
||||
* This field allows the driver to associate private context or state with the
|
||||
* device, such as controller registers or internal buffers.
|
||||
*/
|
||||
void *PrivateData;
|
||||
};
|
||||
|
||||
#ifndef __kernel__
|
||||
/**
|
||||
* @brief Registers a block device with the kernel block subsystem.
|
||||
*
|
||||
* This function should be called by block device drivers after initializing
|
||||
* a device. The kernel will take ownership of the device structure and assign
|
||||
* it a unique device ID. The device will then be accessible for filesystem
|
||||
* mounting and I/O operations.
|
||||
*
|
||||
* @param Device Pointer to a fully initialized BlockDevice structure. All required fields must be set and valid for the lifetime of the device.
|
||||
* @return Device ID (dev_t) assigned by the kernel on success, or an error code on failure.
|
||||
*/
|
||||
dev_t RegisterBlockDevice(struct BlockDevice *Device);
|
||||
|
||||
/**
|
||||
* @brief Unregisters a block device from the kernel block subsystem.
|
||||
*
|
||||
* This function should be called by drivers when a device is being removed
|
||||
* or is no longer available. The kernel will release any resources associated
|
||||
* with the device and invalidate its device ID.
|
||||
*
|
||||
* @param DeviceID The device ID (dev_t) previously returned by RegisterBlockDevice().
|
||||
* @return 0 on success, or an error code.
|
||||
*/
|
||||
int UnregisterBlockDevice(dev_t DeviceID);
|
||||
#endif // __kernel__
|
||||
|
||||
#endif // __FENNIX_API_BLOCK_H__
|
@ -69,7 +69,10 @@ typedef enum
|
||||
BLOCK_TYPE_FLOPPY = DEVICE_TYPE_BLOCK + 128,
|
||||
} DeviceType;
|
||||
|
||||
#ifndef __kernel__
|
||||
EXTERNC dev_t CreateDeviceFile(const char *name, mode_t mode, const struct InodeOperations *Operations);
|
||||
EXTERNC dev_t RegisterDevice(DeviceType Type, const struct InodeOperations *Operations);
|
||||
EXTERNC int UnregisterDevice(dev_t Device);
|
||||
#endif // !__kernel__
|
||||
|
||||
#endif // !__FENNIX_API_DEVICE_H__
|
||||
|
File diff suppressed because it is too large
Load Diff
109
Drivers/include/fcntl.h
Normal file
109
Drivers/include/fcntl.h
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_API_FCNTL_H__
|
||||
#define __FENNIX_API_FCNTL_H__
|
||||
|
||||
#ifdef __kernel__
|
||||
#include <types.h>
|
||||
#endif
|
||||
|
||||
/* cmd */
|
||||
#define F_DUPFD 0x1
|
||||
#define F_DUPFD_CLOEXEC 0x101
|
||||
#define F_DUPFD_CLOFORK 0x201
|
||||
#define F_GETFD 0x2
|
||||
#define F_SETFD 0x3
|
||||
#define F_GETFL 0x4
|
||||
#define F_SETFL 0x5
|
||||
#define F_GETLK 0x6
|
||||
#define F_SETLK 0x7
|
||||
#define F_SETLKW 0x8
|
||||
#define F_OFD_GETLK 0x9
|
||||
#define F_OFD_SETLK 0xA
|
||||
#define F_OFD_SETLKW 0xB
|
||||
#define F_GETOWN 0xC
|
||||
#define F_GETOWN_EX 0xD
|
||||
#define F_SETOWN 0xE
|
||||
#define F_SETOWN_EX 0xF
|
||||
|
||||
#define FD_CLOEXEC 0x1
|
||||
#define FD_CLOFORK 0x2
|
||||
|
||||
/* l_type */
|
||||
#define F_RDLCK 0x1
|
||||
#define F_UNLCK 0x2
|
||||
#define F_WRLCK 0x3
|
||||
|
||||
/* type */
|
||||
#define F_OWNER_PID 0
|
||||
#define F_OWNER_PGRP 1
|
||||
|
||||
/* oflag */
|
||||
#define O_CLOEXEC 02000000
|
||||
#define O_CLOFORK 04000000
|
||||
#define O_CREAT 0x8
|
||||
#define O_DIRECTORY 0200000
|
||||
#define O_EXCL 0x20
|
||||
#define O_NOCTTY 0x40
|
||||
#define O_NOFOLLOW 0400000
|
||||
#define O_TRUNC 0x400
|
||||
#define O_TTY_INIT 0x800
|
||||
|
||||
#define O_APPEND 0x4
|
||||
#define O_DSYNC 0x10
|
||||
#define O_NONBLOCK 0x80
|
||||
#define O_RSYNC 0x100
|
||||
#define O_SYNC 0x200
|
||||
|
||||
#define O_ACCMODE 0x3
|
||||
|
||||
#define O_EXEC 0x4
|
||||
#define O_RDONLY 0x1
|
||||
#define O_RDWR 0x3
|
||||
#define O_SEARCH 0x10
|
||||
#define O_WRONLY 0x2
|
||||
|
||||
#define AT_FDCWD
|
||||
#define AT_EACCESS
|
||||
#define AT_SYMLINK_NOFOLLOW
|
||||
#define AT_SYMLINK_FOLLOW
|
||||
#define AT_REMOVEDIR
|
||||
|
||||
#define POSIX_FADV_DONTNEED
|
||||
#define POSIX_FADV_NOREUSE
|
||||
#define POSIX_FADV_NORMAL
|
||||
#define POSIX_FADV_RANDOM
|
||||
#define POSIX_FADV_SEQUENTIAL
|
||||
#define POSIX_FADV_WILLNEED
|
||||
|
||||
typedef struct f_owner_ex
|
||||
{
|
||||
int type; /* Discriminator for pid. */
|
||||
pid_t pid; /* Process ID or process group ID. */
|
||||
} f_owner_ex;
|
||||
|
||||
typedef struct flock
|
||||
{
|
||||
short l_type; /* Type of lock; F_RDLCK, F_WRLCK, F_UNLCK. */
|
||||
short l_whence; /* Flag for starting offset. */
|
||||
off_t l_start; /* Relative offset in bytes. */
|
||||
off_t l_len; /* Size; if 0 then until EOF. */
|
||||
pid_t l_pid; /* For a process-owned file lock, ignored on input or the process ID of the owning process on output; for an OFD-owned file lock, zero on input or (pid_t)-1 on output. */
|
||||
} flock;
|
||||
|
||||
#endif // !__FENNIX_API_FCNTL_H__
|
@ -95,16 +95,6 @@
|
||||
/** Other: X */
|
||||
#define S_IXOTH 0001
|
||||
|
||||
#define O_RDONLY 00
|
||||
#define O_WRONLY 01
|
||||
#define O_RDWR 02
|
||||
#define O_CREAT 0100
|
||||
#define O_EXCL 0200
|
||||
#define O_TRUNC 01000
|
||||
#define O_APPEND 02000
|
||||
#define O_NOFOLLOW 0400000
|
||||
#define O_CLOEXEC 02000000
|
||||
|
||||
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
||||
#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
|
||||
#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
|
||||
@ -146,10 +136,10 @@ static_assert(sizeof(blkcnt_t) == 8, "blkcnt_t must be 64 bits");
|
||||
#else
|
||||
static_assert(sizeof(dev_t) == 4, "dev_t must be 32 bits");
|
||||
static_assert(sizeof(ino_t) == 4, "ino_t must be 32 bits");
|
||||
static_assert(sizeof(mode_t) == 2, "mode_t must be 16 bits");
|
||||
static_assert(sizeof(nlink_t) == 2, "nlink_t must be 16 bits");
|
||||
static_assert(sizeof(uid_t) == 2, "uid_t must be 16 bits");
|
||||
static_assert(sizeof(gid_t) == 2, "gid_t must be 16 bits");
|
||||
static_assert(sizeof(mode_t) == 4, "mode_t must be 32 bits");
|
||||
static_assert(sizeof(nlink_t) == 4, "nlink_t must be 32 bits");
|
||||
static_assert(sizeof(uid_t) == 4, "uid_t must be 32 bits");
|
||||
static_assert(sizeof(gid_t) == 4, "gid_t must be 32 bits");
|
||||
static_assert(sizeof(off_t) == 4, "off_t must be 32 bits");
|
||||
static_assert(sizeof(time_t) == 4, "time_t must be 32 bits");
|
||||
static_assert(sizeof(blksize_t) == 4, "blksize_t must be 32 bits");
|
||||
@ -332,11 +322,29 @@ struct InodeOperations
|
||||
int (*Stat)(struct Inode *Node, struct kstat *Stat);
|
||||
} __attribute__((packed));
|
||||
|
||||
#define I_FLAG_ROOT 0x1
|
||||
#define I_FLAG_MOUNTPOINT 0x2
|
||||
#define I_FLAG_CACHE_KEEP 0x4
|
||||
|
||||
struct FileSystemInfo;
|
||||
|
||||
struct FileSystemDevice
|
||||
{
|
||||
struct
|
||||
{
|
||||
/**
|
||||
* @brief Inode
|
||||
*
|
||||
* If the device is a block device, this will be NULL.
|
||||
*/
|
||||
struct Inode *node;
|
||||
struct InodeOperations *ops;
|
||||
} inode;
|
||||
|
||||
/**
|
||||
* @brief Block Device
|
||||
*
|
||||
* If the device is a block device, this will be non-NULL.
|
||||
*/
|
||||
struct BlockDevice *Block;
|
||||
};
|
||||
|
||||
struct SuperBlockOperations
|
||||
{
|
||||
int (*AllocateInode)(struct FileSystemInfo *Info, struct Inode **Result);
|
||||
@ -347,7 +355,8 @@ struct SuperBlockOperations
|
||||
*
|
||||
* Write all pending changes to the disk.
|
||||
*
|
||||
* @param Info Inode to synchronize. If NULL, synchronize all inodes.
|
||||
* @param Info Inode to synchronize.
|
||||
* @param Node Inode to synchronize. If NULL, synchronize all inodes.
|
||||
*
|
||||
* @return Zero on success, otherwise an error code.
|
||||
*/
|
||||
@ -363,20 +372,62 @@ struct SuperBlockOperations
|
||||
* @return Zero on success, otherwise an error code.
|
||||
*/
|
||||
int (*Destroy)(struct FileSystemInfo *Info);
|
||||
|
||||
/**
|
||||
* Probe the filesystem.
|
||||
*
|
||||
* Check if the filesystem is supported by the driver.
|
||||
*
|
||||
* @param Device Device to probe.
|
||||
*
|
||||
* @return Zero on success, otherwise an error code.
|
||||
*/
|
||||
int (*Probe)(struct FileSystemDevice *Device);
|
||||
|
||||
/**
|
||||
* Mount the filesystem.
|
||||
*
|
||||
* Mount the filesystem on the given device.
|
||||
*
|
||||
* @param FS Filesystem to mount.
|
||||
* @param Root Pointer to the root inode.
|
||||
* @param Device Device to mount. This pointer will be undefined after the function returns!
|
||||
*
|
||||
* @return Zero on success, otherwise an error code.
|
||||
*/
|
||||
int (*Mount)(struct FileSystemInfo *FS, struct Inode **Root, struct FileSystemDevice *Device);
|
||||
|
||||
/**
|
||||
* Unmount the filesystem.
|
||||
*
|
||||
* Unmount the filesystem from the given device.
|
||||
*
|
||||
* @param FS Filesystem to unmount.
|
||||
*
|
||||
* @return Zero on success, otherwise an error code.
|
||||
*/
|
||||
int (*Unmount)(struct FileSystemInfo *FS);
|
||||
} __attribute__((packed));
|
||||
|
||||
struct FileSystemInfo
|
||||
{
|
||||
const char *Name;
|
||||
const char *RootName;
|
||||
|
||||
int Flags;
|
||||
int Capabilities;
|
||||
|
||||
struct SuperBlockOperations SuperOps;
|
||||
struct InodeOperations Ops;
|
||||
|
||||
void *PrivateData;
|
||||
} __attribute__((packed));
|
||||
|
||||
#ifndef __kernel__
|
||||
dev_t RegisterMountPoint(FileSystemInfo *fsi, Inode *Root);
|
||||
int UnregisterMountPoint(dev_t Device);
|
||||
|
||||
dev_t RegisterFileSystem(struct FileSystemInfo *Info, struct Inode *Root);
|
||||
int UnregisterFileSystem(dev_t Device);
|
||||
#endif // !__kernel__
|
||||
|
||||
#endif // !__FENNIX_API_FILESYSTEM_H__
|
||||
|
@ -239,6 +239,8 @@ typedef struct
|
||||
};
|
||||
} InputReport;
|
||||
|
||||
#ifndef __kernel__
|
||||
EXTERNC int ReportInputEvent(InputReport *Report);
|
||||
#endif // !__kernel__
|
||||
|
||||
#endif // !__FENNIX_API_INPUT_H__
|
||||
|
@ -75,7 +75,7 @@ extern "C"
|
||||
: "dN"(Port), "a"(Data));
|
||||
}
|
||||
|
||||
static inline uint8_t mmioin8(uint64_t Address)
|
||||
static inline uint8_t mmioin8(uintptr_t Address)
|
||||
{
|
||||
__asm__ volatile("" ::
|
||||
: "memory");
|
||||
@ -85,7 +85,7 @@ extern "C"
|
||||
return Result;
|
||||
}
|
||||
|
||||
static inline uint16_t mmioin16(uint64_t Address)
|
||||
static inline uint16_t mmioin16(uintptr_t Address)
|
||||
{
|
||||
__asm__ volatile("" ::
|
||||
: "memory");
|
||||
@ -95,7 +95,7 @@ extern "C"
|
||||
return Result;
|
||||
}
|
||||
|
||||
static inline uint32_t mmioin32(uint64_t Address)
|
||||
static inline uint32_t mmioin32(uintptr_t Address)
|
||||
{
|
||||
__asm__ volatile("" ::
|
||||
: "memory");
|
||||
@ -105,17 +105,17 @@ extern "C"
|
||||
return Result;
|
||||
}
|
||||
|
||||
static inline uint64_t mmioin64(uint64_t Address)
|
||||
static inline uintptr_t mmioin64(uintptr_t Address)
|
||||
{
|
||||
__asm__ volatile("" ::
|
||||
: "memory");
|
||||
uint64_t Result = *(volatile uint64_t *)Address;
|
||||
uintptr_t Result = *(volatile uintptr_t *)Address;
|
||||
__asm__ volatile("" ::
|
||||
: "memory");
|
||||
return Result;
|
||||
}
|
||||
|
||||
static inline void mmioout8(uint64_t Address, uint8_t Data)
|
||||
static inline void mmioout8(uintptr_t Address, uint8_t Data)
|
||||
{
|
||||
__asm__ volatile("" ::
|
||||
: "memory");
|
||||
@ -124,7 +124,7 @@ extern "C"
|
||||
: "memory");
|
||||
}
|
||||
|
||||
static inline void mmioout16(uint64_t Address, uint16_t Data)
|
||||
static inline void mmioout16(uintptr_t Address, uint16_t Data)
|
||||
{
|
||||
__asm__ volatile("" ::
|
||||
: "memory");
|
||||
@ -133,7 +133,7 @@ extern "C"
|
||||
: "memory");
|
||||
}
|
||||
|
||||
static inline void mmioout32(uint64_t Address, uint32_t Data)
|
||||
static inline void mmioout32(uintptr_t Address, uint32_t Data)
|
||||
{
|
||||
__asm__ volatile("" ::
|
||||
: "memory");
|
||||
@ -142,11 +142,11 @@ extern "C"
|
||||
: "memory");
|
||||
}
|
||||
|
||||
static inline void mmioout64(uint64_t Address, uint64_t Data)
|
||||
static inline void mmioout64(uintptr_t Address, uintptr_t Data)
|
||||
{
|
||||
__asm__ volatile("" ::
|
||||
: "memory");
|
||||
*(volatile uint64_t *)Address = Data;
|
||||
*(volatile uintptr_t *)Address = Data;
|
||||
__asm__ volatile("" ::
|
||||
: "memory");
|
||||
}
|
||||
@ -175,10 +175,10 @@ extern "C"
|
||||
: "memory");
|
||||
}
|
||||
|
||||
static inline void mmoutq(void *Address, uint64_t Value)
|
||||
static inline void mmoutq(void *Address, uintptr_t Value)
|
||||
{
|
||||
__asm__ volatile("mov %1, %0"
|
||||
: "=m"((*(uint64_t *)(Address)))
|
||||
: "=m"((*(uintptr_t *)(Address)))
|
||||
: "r"(Value)
|
||||
: "memory");
|
||||
}
|
||||
@ -213,12 +213,12 @@ extern "C"
|
||||
return Result;
|
||||
}
|
||||
|
||||
static inline uint64_t mminq(void *Address)
|
||||
static inline uintptr_t mminq(void *Address)
|
||||
{
|
||||
uint64_t Result;
|
||||
uintptr_t Result;
|
||||
__asm__ volatile("mov %1, %0"
|
||||
: "=r"(Result)
|
||||
: "m"((*(uint64_t *)(Address)))
|
||||
: "m"((*(uintptr_t *)(Address)))
|
||||
: "memory");
|
||||
return Result;
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_API_PCI_H__
|
||||
@ -171,11 +171,13 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#ifndef __kernel__
|
||||
PCIArray *GetPCIDevices(uint16_t Vendors[], uint16_t Devices[]);
|
||||
void InitializePCI(PCIDevice *Device);
|
||||
uint32_t GetBAR(uint8_t Index, PCIDevice *Device);
|
||||
uint8_t iLine(PCIDevice *Device);
|
||||
uint8_t iPin(PCIDevice *Device);
|
||||
#endif // !__kernel__
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -71,7 +71,7 @@ typedef uint32_t uid_t;
|
||||
typedef uint32_t gid_t;
|
||||
typedef int64_t clock_t;
|
||||
typedef int32_t pid_t;
|
||||
#elif defined(__LP32__)
|
||||
#else
|
||||
typedef int32_t off_t;
|
||||
typedef long long off64_t;
|
||||
typedef __INT32_TYPE__ mode_t;
|
||||
|
@ -1,5 +1,9 @@
|
||||
build:
|
||||
make -C aip build
|
||||
MAKE_TARGETS := build clean
|
||||
DIRECTORIES := $(sort $(dir $(wildcard ./*/)))
|
||||
|
||||
clean:
|
||||
make -C aip clean
|
||||
.PHONY: $(MAKE_TARGETS) $(DIRECTORIES)
|
||||
|
||||
$(MAKE_TARGETS): $(DIRECTORIES)
|
||||
|
||||
$(DIRECTORIES):
|
||||
$(MAKE) -C $@ $(MAKECMDGOALS)
|
||||
|
@ -1,22 +0,0 @@
|
||||
# Config files
|
||||
include ../../../Makefile.conf
|
||||
include ../../config.mk
|
||||
|
||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
||||
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
|
||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||
|
||||
FILENAME = aip.drv
|
||||
|
||||
build: $(FILENAME)
|
||||
mv $(FILENAME) ../../out/$(FILENAME)
|
||||
|
||||
$(FILENAME): $(OBJ)
|
||||
$(info Linking $@)
|
||||
$(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@
|
||||
|
||||
clean:
|
||||
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_DRIVER_AIP_H__
|
||||
#define __FENNIX_DRIVER_AIP_H__
|
||||
|
||||
#include <types.h>
|
||||
#include <aip.h>
|
||||
#include <regs.h>
|
||||
|
||||
extern uint8_t Device1ID[];
|
||||
extern uint8_t Device2ID[];
|
||||
|
||||
void PS2KbdInterruptHandler(TrapFrame *);
|
||||
int InitializeKeyboard();
|
||||
int FinalizeKeyboard();
|
||||
int DetectPS2Keyboard();
|
||||
|
||||
void PS2MouseInterruptHandler(TrapFrame *);
|
||||
int InitializeMouse();
|
||||
int FinalizeMouse();
|
||||
int DetectPS2Mouse();
|
||||
int DetectUART();
|
||||
|
||||
#endif // !__FENNIX_DRIVER_AIP_H__
|
@ -1,235 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "aip.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <base.h>
|
||||
|
||||
bool IsKeyboard(uint8_t ID)
|
||||
{
|
||||
/* Common keyboard IDs */
|
||||
return ID == 0xAB || ID == 0xAC || ID == 0x5D ||
|
||||
ID == 0x2B || ID == 0x47 || ID == 0x60;
|
||||
}
|
||||
|
||||
bool IsMouse(uint8_t ID)
|
||||
{
|
||||
/* Common mouse IDs */
|
||||
return ID == 0x00 || ID == 0x03 || ID == 0x04;
|
||||
}
|
||||
|
||||
const char *GetPS2DeviceName(uint8_t ID, uint8_t SubID)
|
||||
{
|
||||
switch (ID)
|
||||
{
|
||||
case 0x00:
|
||||
return "Standard PS/2 Mouse";
|
||||
case 0x03:
|
||||
return "Mouse with scroll wheel";
|
||||
case 0x04:
|
||||
return "Mouse 5 buttons";
|
||||
case 0xAB:
|
||||
{
|
||||
switch (SubID)
|
||||
{
|
||||
case 0x83: /* Normal */
|
||||
case 0x41: /* Translated */
|
||||
case 0xC1: /* Normal + Translated */
|
||||
return "Standard PS/2 Keyboard";
|
||||
case 0x84:
|
||||
case 0x54:
|
||||
return "IBM Thinkpad/Spacesaver Keyboard";
|
||||
case 0x85:
|
||||
return "NCD N-97/122-Key Host Connect(ed) Keyboard";
|
||||
case 0x86:
|
||||
return "122-Key Keyboard";
|
||||
case 0x90:
|
||||
return "Japanese \"G\" Keyboard";
|
||||
case 0x91:
|
||||
return "Japanese \"P\" Keyboard";
|
||||
case 0x92:
|
||||
return "Japanese \"A\" Keyboard";
|
||||
default:
|
||||
return "Unknown PS/2 Keyboard";
|
||||
}
|
||||
}
|
||||
case 0xAC:
|
||||
{
|
||||
switch (SubID)
|
||||
{
|
||||
case 0xA1:
|
||||
return "NCD Sun Keyboard";
|
||||
default:
|
||||
return "Unknown NCD Sun Keyboard";
|
||||
}
|
||||
}
|
||||
case 0x5D:
|
||||
case 0x2B:
|
||||
return "Trust Keyboard";
|
||||
case 0x47:
|
||||
case 0x60:
|
||||
return "NMB SGI Keyboard";
|
||||
default:
|
||||
return "Unknown PS/2 Device";
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t Device1ID[2] = {0x00, 0x00};
|
||||
uint8_t Device2ID[2] = {0x00, 0x00};
|
||||
bool DualChannel = false;
|
||||
|
||||
int DriverEntry()
|
||||
{
|
||||
PS2WriteCommand(PS2_CMD_DISABLE_PORT_1);
|
||||
PS2WriteCommand(PS2_CMD_DISABLE_PORT_2);
|
||||
PS2ClearOutputBuffer();
|
||||
|
||||
PS2WriteCommand(PS2_CMD_READ_CONFIG);
|
||||
PS2_CONFIGURATION cfg = {.Raw = PS2ReadData()};
|
||||
|
||||
DualChannel = cfg.Port2Clock;
|
||||
if (DualChannel)
|
||||
KernelLog("Dual channel PS/2 controller detected");
|
||||
cfg.Port1Interrupt = 1;
|
||||
cfg.Port2Interrupt = 1;
|
||||
cfg.Port1Translation = 1;
|
||||
|
||||
PS2WriteCommand(PS2_CMD_WRITE_CONFIG);
|
||||
PS2WriteData(cfg.Raw);
|
||||
|
||||
PS2WriteCommand(PS2_CMD_TEST_CONTROLLER);
|
||||
uint8_t test = PS2ReadData();
|
||||
if (test != PS2_TEST_PASSED)
|
||||
{
|
||||
KernelLog("PS/2 controller self test failed (%#x)", test);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
PS2WriteCommand(PS2_CMD_WRITE_CONFIG);
|
||||
PS2WriteData(cfg.Raw);
|
||||
|
||||
// bool port2avail = false;
|
||||
// if (DualChannel)
|
||||
// {
|
||||
// PS2WriteCommand(PS2_CMD_ENABLE_PORT_1);
|
||||
// PS2WriteCommand(PS2_CMD_READ_CONFIG);
|
||||
// cfg.Raw = PS2ReadData();
|
||||
// port2avail = cfg.Port2Clock;
|
||||
// PS2WriteCommand(PS2_CMD_DISABLE_PORT_1);
|
||||
// }
|
||||
|
||||
PS2WriteCommand(PS2_CMD_TEST_PORT_1);
|
||||
test = PS2ReadData();
|
||||
if (test != 0x00)
|
||||
{
|
||||
KernelLog("PS/2 Port 1 self test failed (%#x)", test);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (DualChannel)
|
||||
{
|
||||
PS2WriteCommand(PS2_CMD_TEST_PORT_2);
|
||||
test = PS2ReadData();
|
||||
if (test != 0x00)
|
||||
{
|
||||
KernelLog("PS/2 Port 2 self test failed (%#x)", test);
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
PS2WriteCommand(PS2_CMD_ENABLE_PORT_1);
|
||||
if (DualChannel)
|
||||
PS2WriteCommand(PS2_CMD_ENABLE_PORT_2);
|
||||
|
||||
int errK = InitializeKeyboard();
|
||||
|
||||
int errM = 0;
|
||||
if (DualChannel)
|
||||
errM = InitializeMouse();
|
||||
|
||||
/** A device may fail, but if the other one works,
|
||||
* we can still use it.
|
||||
*/
|
||||
if (errK != 0 && errM != 0)
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DriverFinal()
|
||||
{
|
||||
FinalizeKeyboard();
|
||||
FinalizeMouse();
|
||||
PS2WriteCommand(PS2_CMD_DISABLE_PORT_1);
|
||||
PS2WriteCommand(PS2_CMD_DISABLE_PORT_2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DriverPanic()
|
||||
{
|
||||
PS2WriteCommand(PS2_CMD_DISABLE_PORT_1);
|
||||
PS2WriteCommand(PS2_CMD_DISABLE_PORT_2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __intStub() {}
|
||||
int DriverProbe()
|
||||
{
|
||||
RegisterInterruptHandler(1, __intStub);
|
||||
RegisterInterruptHandler(12, __intStub);
|
||||
|
||||
int kbd = DetectPS2Keyboard();
|
||||
int mouse = DetectPS2Mouse();
|
||||
int uart = DetectUART();
|
||||
|
||||
UnregisterAllInterruptHandlers(__intStub);
|
||||
|
||||
if (kbd != 0 && mouse != 0 && uart != 0)
|
||||
return -ENODEV;
|
||||
|
||||
if (kbd == 0)
|
||||
{
|
||||
if (!IsKeyboard(Device1ID[0]))
|
||||
{
|
||||
KernelLog("PS/2 Port 1 is not a keyboard");
|
||||
// return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (mouse == 0)
|
||||
{
|
||||
if (!IsMouse(Device2ID[0]))
|
||||
{
|
||||
KernelLog("PS/2 Port 2 is not a mouse");
|
||||
// return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
KernelPrint("PS/2 Port 1: %s (0x%X 0x%X)",
|
||||
GetPS2DeviceName(Device1ID[0], Device1ID[1]),
|
||||
Device1ID[0], Device1ID[1]);
|
||||
KernelPrint("PS/2 Port 2: %s (0x%X 0x%X)",
|
||||
GetPS2DeviceName(Device2ID[0], Device2ID[1]),
|
||||
Device2ID[0], Device2ID[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DriverInfo("aip",
|
||||
"Advanced Integrated Peripheral Driver",
|
||||
"EnderIce2",
|
||||
0, 0, 1,
|
||||
"GPLv3");
|
@ -1,244 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "aip.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <base.h>
|
||||
#include <fs.h>
|
||||
#include <input.h>
|
||||
|
||||
dev_t MouseDevID = -1;
|
||||
bool PacketReady = false;
|
||||
bool FourPackets = false;
|
||||
bool MouseButton45 = false;
|
||||
uint8_t Cycle = 0;
|
||||
PS2_MOUSE_PACKET Packet = {0};
|
||||
|
||||
InputReport mir = {0};
|
||||
void PS2MouseInterruptHandler(TrapFrame *)
|
||||
{
|
||||
uint8_t data = PS2ReadData();
|
||||
if (data == PS2_MOUSE_RESP_ACK ||
|
||||
data == PS2_MOUSE_RESP_RESEND)
|
||||
return;
|
||||
|
||||
if (!PacketReady)
|
||||
{
|
||||
switch (Cycle)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
if ((data & 0b00001000 /* Always 1 */) == 0)
|
||||
return;
|
||||
|
||||
Packet.Base.Raw = data;
|
||||
Cycle++;
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
Packet.XMovement = data;
|
||||
Cycle++;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
Packet.YMovement = data;
|
||||
if (FourPackets)
|
||||
Cycle++;
|
||||
else
|
||||
{
|
||||
Cycle = 0;
|
||||
PacketReady = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
Packet.ZMovement.Raw = data;
|
||||
Cycle = 0;
|
||||
PacketReady = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* https://stackoverflow.com/a/3208376/9352057 */
|
||||
#define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
|
||||
#define BYTE_TO_BINARY(byte) \
|
||||
((byte) & 0x80 ? '1' : '0'), \
|
||||
((byte) & 0x40 ? '1' : '0'), \
|
||||
((byte) & 0x20 ? '1' : '0'), \
|
||||
((byte) & 0x10 ? '1' : '0'), \
|
||||
((byte) & 0x08 ? '1' : '0'), \
|
||||
((byte) & 0x04 ? '1' : '0'), \
|
||||
((byte) & 0x02 ? '1' : '0'), \
|
||||
((byte) & 0x01 ? '1' : '0')
|
||||
|
||||
DebugLog("PS/2 Mouse Packet: [" BYTE_TO_BINARY_PATTERN ":" BYTE_TO_BINARY_PATTERN ":" BYTE_TO_BINARY_PATTERN ":" BYTE_TO_BINARY_PATTERN "] LB:%d RB:%d MB:%d A1:%d XS:%d YS:%d XO:%d YO:%d | X:%03d Y:%03d | Z:%d B4:%d B5:%d A0:%d A0:%d",
|
||||
BYTE_TO_BINARY(Packet.Base.Raw),
|
||||
BYTE_TO_BINARY(Packet.XMovement),
|
||||
BYTE_TO_BINARY(Packet.YMovement),
|
||||
BYTE_TO_BINARY(Packet.ZMovement.Raw),
|
||||
Packet.Base.LeftButton, Packet.Base.RightButton, Packet.Base.MiddleButton,
|
||||
Packet.Base.Always1,
|
||||
Packet.Base.XSign, Packet.Base.YSign,
|
||||
Packet.Base.XOverflow, Packet.Base.YOverflow,
|
||||
Packet.XMovement, Packet.YMovement,
|
||||
Packet.ZMovement.Z, Packet.ZMovement.Button4, Packet.ZMovement.Button5,
|
||||
Packet.ZMovement.Always0, Packet.ZMovement.Always0_2);
|
||||
|
||||
int X, Y;
|
||||
X = Packet.XMovement - (Packet.Base.XSign ? 256 : 0);
|
||||
Y = Packet.YMovement - (Packet.Base.YSign ? 256 : 0);
|
||||
|
||||
if (Packet.Base.XOverflow)
|
||||
X = 0;
|
||||
|
||||
if (Packet.Base.YOverflow)
|
||||
Y = 0;
|
||||
|
||||
mir.Type = INPUT_TYPE_MOUSE;
|
||||
mir.Device = MouseDevID;
|
||||
mir.Mouse.LeftButton = Packet.Base.LeftButton;
|
||||
mir.Mouse.RightButton = Packet.Base.RightButton;
|
||||
mir.Mouse.MiddleButton = Packet.Base.MiddleButton;
|
||||
mir.Mouse.Button4 = Packet.ZMovement.Button4;
|
||||
mir.Mouse.Button5 = Packet.ZMovement.Button5;
|
||||
mir.Mouse.X = X;
|
||||
mir.Mouse.Y = -Y;
|
||||
mir.Mouse.Z = Packet.ZMovement.Z;
|
||||
ReportInputEvent(&mir);
|
||||
PacketReady = false;
|
||||
}
|
||||
|
||||
void MouseSampleRate(uint8_t SampleRate)
|
||||
{
|
||||
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
||||
PS2WriteData(PS2_MOUSE_CMD_SET_SAMPLE_RATE);
|
||||
PS2ReadData();
|
||||
|
||||
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
||||
PS2WriteData(SampleRate);
|
||||
PS2ReadData();
|
||||
}
|
||||
|
||||
int __fs_ms_Ioctl(struct Inode *, unsigned long, void *)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct InodeOperations MouseOps = {
|
||||
.Ioctl = __fs_ms_Ioctl,
|
||||
};
|
||||
|
||||
int InitializeMouse()
|
||||
{
|
||||
PS2WriteData(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
||||
PS2WriteData(PS2_MOUSE_CMD_RESET);
|
||||
uint8_t test = PS2ReadData();
|
||||
if (test != PS2_MOUSE_RESP_TEST_PASSED &&
|
||||
test != PS2_MOUSE_RESP_ACK)
|
||||
{
|
||||
KernelLog("PS/2 mouse reset failed! (%#x)", test);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
RegisterInterruptHandler(12, PS2MouseInterruptHandler);
|
||||
|
||||
MouseDevID = RegisterDevice(INPUT_TYPE_MOUSE, &MouseOps);
|
||||
|
||||
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
||||
PS2WriteData(PS2_MOUSE_CMD_SET_DEFAULTS);
|
||||
PS2ReadData();
|
||||
|
||||
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
||||
PS2WriteData(PS2_MOUSE_CMD_ENABLE_DATA_REPORTING);
|
||||
|
||||
MouseSampleRate(200);
|
||||
MouseSampleRate(100);
|
||||
MouseSampleRate(80);
|
||||
|
||||
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
||||
PS2WriteData(PS2_MOUSE_CMD_READ_ID);
|
||||
uint8_t Device2ID = PS2ReadData();
|
||||
KernelLog("PS/2 Mouse ID: %#x", Device2ID);
|
||||
|
||||
MouseSampleRate(200);
|
||||
MouseSampleRate(200);
|
||||
MouseSampleRate(80);
|
||||
|
||||
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
||||
PS2WriteData(PS2_MOUSE_CMD_READ_ID);
|
||||
Device2ID = PS2ReadData();
|
||||
KernelLog("PS/2 Mouse ID: %#x", Device2ID);
|
||||
|
||||
if (Device2ID >= 3 && Device2ID <= 4)
|
||||
FourPackets = true;
|
||||
if (Device2ID == 4)
|
||||
MouseButton45 = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FinalizeMouse()
|
||||
{
|
||||
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
||||
PS2WriteData(PS2_MOUSE_CMD_DISABLE_DATA_REPORTING);
|
||||
|
||||
UnregisterDevice(MouseDevID);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DetectPS2Mouse()
|
||||
{
|
||||
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
||||
PS2WriteData(PS2_MOUSE_CMD_DISABLE_DATA_REPORTING);
|
||||
if (PS2ACKTimeout() != 0)
|
||||
KernelLog("PS/2 mouse failed to disable data reporting!");
|
||||
|
||||
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
||||
PS2WriteData(PS2_MOUSE_CMD_READ_ID);
|
||||
if (PS2ACKTimeout() != 0)
|
||||
KernelLog("PS/2 mouse failed to read ID!");
|
||||
|
||||
uint8_t recByte;
|
||||
int timeout = 1000000;
|
||||
while (timeout--)
|
||||
{
|
||||
recByte = PS2ReadData();
|
||||
if (recByte != PS2_ACK)
|
||||
break;
|
||||
}
|
||||
Device2ID[0] = recByte;
|
||||
|
||||
timeout = 1000000;
|
||||
while (timeout--)
|
||||
{
|
||||
recByte = PS2ReadData();
|
||||
if (recByte != PS2_ACK)
|
||||
break;
|
||||
}
|
||||
Device2ID[1] = recByte;
|
||||
|
||||
KernelLog("PS2 Mouse Device: 0x%X 0x%X", Device2ID[0], Device2ID[1]);
|
||||
return 0;
|
||||
}
|
@ -1,646 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "aip.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <base.h>
|
||||
#include <fs.h>
|
||||
#include <input.h>
|
||||
#include <io.h>
|
||||
|
||||
#define SERIAL_ENABLE_DLAB 0x80
|
||||
#define SERIAL_BUFFER_EMPTY 0x20
|
||||
|
||||
enum Ports
|
||||
{
|
||||
COM1 = 0x3F8,
|
||||
COM2 = 0x2F8,
|
||||
COM3 = 0x3E8,
|
||||
COM4 = 0x2E8,
|
||||
COM5 = 0x5F8,
|
||||
COM6 = 0x4F8,
|
||||
COM7 = 0x5E8,
|
||||
COM8 = 0x4E8,
|
||||
|
||||
LPT1 = 0x378,
|
||||
LPT2 = 0x278,
|
||||
LPT3 = 0x3BC
|
||||
};
|
||||
|
||||
enum SerialSpeed
|
||||
{
|
||||
RATE_50_HI = 0x09,
|
||||
RATE_50_LO = 0x00,
|
||||
|
||||
RATE_300_HI = 0x01,
|
||||
RATE_300_LO = 0x80,
|
||||
|
||||
RATE_600_HI = 0x00,
|
||||
RATE_600_LO = 0xC0,
|
||||
|
||||
RATE_2400_HI = 0x00,
|
||||
RATE_2400_LO = 0x30,
|
||||
|
||||
RATE_4800_HI = 0x00,
|
||||
RATE_4800_LO = 0x18,
|
||||
|
||||
RATE_9600_HI = 0x00,
|
||||
RATE_9600_LO = 0x0C,
|
||||
|
||||
RATE_19200_HI = 0x00,
|
||||
RATE_19200_LO = 0x06,
|
||||
|
||||
RATE_38400_HI = 0x00,
|
||||
RATE_38400_LO = 0x03,
|
||||
|
||||
RATE_57600_HI = 0x00,
|
||||
RATE_57600_LO = 0x02,
|
||||
|
||||
RATE_115200_HI = 0x00,
|
||||
RATE_115200_LO = 0x01
|
||||
};
|
||||
|
||||
/*
|
||||
. Table of Registers .
|
||||
/---------------------------------------------------------------------\
|
||||
| Base Address | DLAB | R/W | Abr | Register Name |
|
||||
|---------------------------------------------------------------------|
|
||||
| +0 | =0 | W | - | Transmitter Holding Buffer |
|
||||
| | =0 | R | - | Receiver Buffer |
|
||||
| | =1 | R/W | - | Divisor Latch Low Byte |
|
||||
| +1 | =0 | R/W | IER | Interrupt Enable Register |
|
||||
| | =1 | R/W | - | Divisor Latch High Byte |
|
||||
| +2 | - | R | IIR | Interrupt Identification Register |
|
||||
| | - | W | FCR | FIFO Control Register |
|
||||
| +3 | - | R/W | LCR | Line Control Register |
|
||||
| +4 | - | R/W | MCR | Modem Control Register |
|
||||
| +5 | - | R | LSR | Line Status Register |
|
||||
| +6 | - | R | MSR | Modem Status Register |
|
||||
| +7 | - | R/W | - | Scratch Register |
|
||||
\---------------------------------------------------------------------/
|
||||
|
||||
Source:
|
||||
Interfacing the Serial / RS232 Port V5.0
|
||||
Table 5 : Table of Registers
|
||||
*/
|
||||
|
||||
/** Interrupt Enable Register */
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/* Enable Received Data Available Interrupt */
|
||||
uint8_t InterruptOnReceive : 1;
|
||||
|
||||
/* Enable Transmitter Holding Register Empty Interrupt */
|
||||
uint8_t InterruptOnTransmitter : 1;
|
||||
|
||||
/* Enable Receiver Line Status Interrupt */
|
||||
uint8_t LineStatusInterrupt : 1;
|
||||
|
||||
/* Enable Modem Status Interrupt */
|
||||
uint8_t ModemStatusInterrupt : 1;
|
||||
|
||||
/* Enables Sleep Mode (16750) */
|
||||
uint8_t SleepMode : 1;
|
||||
|
||||
/* Enables Low Power Mode (16750) */
|
||||
uint8_t LowPowerMode : 1;
|
||||
|
||||
/* Reserved */
|
||||
uint8_t __reserved : 2;
|
||||
};
|
||||
uint8_t raw;
|
||||
} IER;
|
||||
|
||||
/** Interrupt Identification Register */
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/* Interrupt pending */
|
||||
uint8_t InterruptPending : 1;
|
||||
|
||||
/**
|
||||
* Interrupt Status
|
||||
*
|
||||
* 00b = Modem Status Interrupt
|
||||
* 01b = Transmitter Holding Register Empty Interrupt
|
||||
* 10b = Received Data Available Interrupt
|
||||
* 11b = Receiver Line Status Interrupt
|
||||
*/
|
||||
uint8_t InterruptStatus : 2;
|
||||
|
||||
/**
|
||||
* 16550 Time-out Interrupt Pending
|
||||
*
|
||||
* @note Reserved on 8250, 16450
|
||||
*/
|
||||
uint8_t TimeOutIP : 1;
|
||||
|
||||
/** Reserved */
|
||||
uint8_t __reserved : 1;
|
||||
|
||||
/** 64 Byte Fifo Enabled (16750 only) */
|
||||
uint8_t FIFO64 : 1;
|
||||
|
||||
/**
|
||||
* Enable FIFO
|
||||
*
|
||||
* 00b = No FIFO
|
||||
* 01b = FIFO Enabled but Unusable
|
||||
* 11b = FIFO Enabled
|
||||
*/
|
||||
uint8_t FIFO : 2;
|
||||
};
|
||||
uint8_t raw;
|
||||
} IIR;
|
||||
|
||||
/** First In / First Out Control Register */
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** Enable FIFO's */
|
||||
uint8_t FIFO : 1;
|
||||
|
||||
/** Clear Receive FIFO */
|
||||
uint8_t ClearRX : 1;
|
||||
|
||||
/** Clear Transmit FIFO */
|
||||
uint8_t ClearTX : 1;
|
||||
|
||||
/** DMA Mode Select.
|
||||
*
|
||||
* Change status of RXRDY & TXRDY pins from mode 1 to mode 2.
|
||||
*/
|
||||
uint8_t DMAMode : 1;
|
||||
|
||||
/** Reserved */
|
||||
uint8_t __reserved : 1;
|
||||
|
||||
/** Enable 64 Byte FIFO (16750 only) */
|
||||
uint8_t FIFO64 : 1;
|
||||
|
||||
/** Interrupt Trigger Level
|
||||
*
|
||||
* 00b = 1 Byte
|
||||
* 01b = 4 Bytes
|
||||
* 10b = 8 Bytes
|
||||
* 11b = 14 Bytes
|
||||
*/
|
||||
uint8_t TriggerLevel : 2;
|
||||
};
|
||||
uint8_t raw;
|
||||
} FCR;
|
||||
|
||||
/** Line Control Register */
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** Word Length
|
||||
*
|
||||
* 00b = 5 bits
|
||||
* 01b = 6 bits
|
||||
* 10b = 7 bits
|
||||
* 11b = 8 bits
|
||||
*/
|
||||
uint8_t WordLength : 2;
|
||||
|
||||
/** Length of Stop Bit
|
||||
*
|
||||
* 0b = One Stop Bit
|
||||
* 1b = 2 Stop bits for words of length 6,7 or 8 bits or 1.5 Stop Bits for Word lengths of 5 bits.
|
||||
*/
|
||||
uint8_t StopBit : 1;
|
||||
|
||||
/** Parity Select
|
||||
*
|
||||
* 0b = No Parity
|
||||
* 001b = Odd Parity
|
||||
* 011b = Even Parity
|
||||
* 101b = High Parity (Sticky)
|
||||
* 111b = Low Parity (Sticky)
|
||||
*/
|
||||
uint8_t Parity : 3;
|
||||
|
||||
/** Set Break Enable */
|
||||
uint8_t SetBreak : 1;
|
||||
|
||||
/**
|
||||
* Divisor Latch Access
|
||||
*
|
||||
* 0b = Access to Receiver buffer, Transmitter buffer & Interrupt Enable Register
|
||||
* 1b = Divisor Latch Access Bit
|
||||
*/
|
||||
uint8_t DLAB : 1;
|
||||
};
|
||||
uint8_t raw;
|
||||
} LCR;
|
||||
|
||||
/** Modem Control Register */
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** Force Data Terminal Ready */
|
||||
uint8_t DataTerminalReady : 1;
|
||||
|
||||
/** Force Request to Send */
|
||||
uint8_t RequestToSend : 1;
|
||||
|
||||
/** Auxiliary Output 1 */
|
||||
uint8_t Out1 : 1;
|
||||
|
||||
/** Auxiliary Output 2 */
|
||||
uint8_t Out2 : 1;
|
||||
|
||||
/** Loopback Mode */
|
||||
uint8_t Loopback : 1;
|
||||
|
||||
/** Autoflow Control Enabled (16750 only) */
|
||||
uint8_t Autoflow : 1;
|
||||
|
||||
/** Reserved */
|
||||
uint8_t __reserved : 2;
|
||||
};
|
||||
uint8_t raw;
|
||||
} MCR;
|
||||
|
||||
/** Line Status Register */
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** Data Ready */
|
||||
uint8_t DataReady : 1;
|
||||
|
||||
/** Overrun Error */
|
||||
uint8_t OverrunError : 1;
|
||||
|
||||
/** Parity Error */
|
||||
uint8_t ParityError : 1;
|
||||
|
||||
/** Framing Error */
|
||||
uint8_t FramingError : 1;
|
||||
|
||||
/** Break Interrupt */
|
||||
uint8_t BreakInterrupt : 1;
|
||||
|
||||
/** Empty Transmitter Holding Register */
|
||||
uint8_t EmptyTransmitterHolding : 1;
|
||||
|
||||
/** Empty Data Holding Registers */
|
||||
uint8_t EmptyDataHolding : 1;
|
||||
|
||||
/** Error in Received FIFO */
|
||||
uint8_t ErrorReceivedFIFO : 1;
|
||||
};
|
||||
uint8_t raw;
|
||||
} LSR;
|
||||
|
||||
/** Modem Status Register */
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** Delta Clear to Send */
|
||||
uint8_t DeltaClearToSend : 1;
|
||||
|
||||
/** Delta Data Set Ready */
|
||||
uint8_t DeltaDataSetReady : 1;
|
||||
|
||||
/** Trailing Edge Ring Indicator */
|
||||
uint8_t TrailingEdgeRingIndicator : 1;
|
||||
|
||||
/** Delta Data Carrier Detect */
|
||||
uint8_t DeltaDataCarrierDetect : 1;
|
||||
|
||||
/** Clear To Send */
|
||||
uint8_t ClearToSend : 1;
|
||||
|
||||
/** Data Set Ready */
|
||||
uint8_t DataSetReady : 1;
|
||||
|
||||
/** Ring Indicator */
|
||||
uint8_t RingIndicator : 1;
|
||||
|
||||
/** Carrier Detect */
|
||||
uint8_t CarrierDetect : 1;
|
||||
};
|
||||
uint8_t raw;
|
||||
} MSR;
|
||||
|
||||
union UARTs
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint8_t com1 : 1;
|
||||
uint8_t com2 : 1;
|
||||
uint8_t com3 : 1;
|
||||
uint8_t com4 : 1;
|
||||
uint8_t com5 : 1;
|
||||
uint8_t com6 : 1;
|
||||
uint8_t com7 : 1;
|
||||
uint8_t com8 : 1;
|
||||
|
||||
uint8_t lpt1 : 1;
|
||||
uint8_t lpt2 : 1;
|
||||
uint8_t lpt3 : 1;
|
||||
|
||||
uint8_t __reserved : 5;
|
||||
};
|
||||
uint16_t raw;
|
||||
} uart;
|
||||
|
||||
bool IsDataReady(uint16_t Port)
|
||||
{
|
||||
LSR lsr;
|
||||
lsr.raw = inb(Port + 5);
|
||||
return lsr.DataReady;
|
||||
}
|
||||
|
||||
bool IsTransmitEmpty(uint16_t Port)
|
||||
{
|
||||
LSR lsr;
|
||||
lsr.raw = inb(Port + 5);
|
||||
return lsr.EmptyTransmitterHolding;
|
||||
}
|
||||
|
||||
char ReadSerial(uint16_t Port)
|
||||
{
|
||||
while (!IsDataReady(Port))
|
||||
Yield();
|
||||
return inb(Port);
|
||||
}
|
||||
|
||||
void WriteSerial(uint16_t Port, char Character)
|
||||
{
|
||||
while (!IsTransmitEmpty(Port))
|
||||
Yield();
|
||||
outb(Port, Character);
|
||||
}
|
||||
|
||||
void ReportSerialReceived(uint8_t Data)
|
||||
{
|
||||
DebugLog("%c", Data);
|
||||
}
|
||||
|
||||
void UartCOM24(TrapFrame *)
|
||||
{
|
||||
LSR lsr2, lsr4;
|
||||
do
|
||||
{
|
||||
lsr2.raw = inb(COM2 + 5);
|
||||
if (lsr2.DataReady)
|
||||
ReportSerialReceived(inb(COM2));
|
||||
lsr4.raw = inb(COM4 + 5);
|
||||
if (lsr4.DataReady)
|
||||
ReportSerialReceived(inb(COM4));
|
||||
} while (lsr2.DataReady || lsr4.DataReady);
|
||||
}
|
||||
|
||||
void UartCOM13(TrapFrame *)
|
||||
{
|
||||
LSR lsr1, lsr3;
|
||||
do
|
||||
{
|
||||
lsr1.raw = inb(COM1 + 5);
|
||||
if (lsr1.DataReady)
|
||||
ReportSerialReceived(inb(COM1));
|
||||
lsr3.raw = inb(COM3 + 5);
|
||||
if (lsr3.DataReady)
|
||||
ReportSerialReceived(inb(COM3));
|
||||
} while (lsr1.DataReady || lsr3.DataReady);
|
||||
}
|
||||
|
||||
bool InitializePort(uint16_t Port)
|
||||
{
|
||||
ECS;
|
||||
LCR lcr = {0};
|
||||
IER ier = {0};
|
||||
FCR fcr = {0};
|
||||
MCR mcr = {0};
|
||||
|
||||
outb(Port + 3, lcr.raw);
|
||||
outb(Port + 1, ier.raw);
|
||||
|
||||
lcr.DLAB = 1;
|
||||
outb(Port + 3, lcr.raw);
|
||||
|
||||
outb(Port + 0, RATE_115200_LO);
|
||||
outb(Port + 1, RATE_115200_HI);
|
||||
|
||||
lcr.DLAB = 0;
|
||||
lcr.WordLength = 0b11;
|
||||
outb(Port + 3, lcr.raw);
|
||||
|
||||
fcr.FIFO = 1;
|
||||
fcr.ClearRX = 1;
|
||||
fcr.ClearTX = 1;
|
||||
fcr.TriggerLevel = 0b11;
|
||||
outb(Port + 2, fcr.raw);
|
||||
|
||||
mcr.DataTerminalReady = 1;
|
||||
mcr.RequestToSend = 1;
|
||||
mcr.Out2 = 1;
|
||||
mcr.Loopback = 1;
|
||||
outb(Port + 4, mcr.raw);
|
||||
|
||||
/* Test the serial port */
|
||||
outb(Port + 0, 0x48);
|
||||
uint8_t result = inb(Port + 0);
|
||||
if (result != 0x48)
|
||||
{
|
||||
/* FIXME: DETECT BAUD RATE
|
||||
Do multiple test to check if the output is garbage.
|
||||
If so, reduce the baud rate until it works. */
|
||||
|
||||
LCS;
|
||||
KernelPrint("Port %#X test failed!", Port);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Set normal operation mode */
|
||||
mcr.DataTerminalReady = 1;
|
||||
mcr.RequestToSend = 1;
|
||||
mcr.Out1 = 1;
|
||||
mcr.Out2 = 1;
|
||||
mcr.Loopback = 0;
|
||||
outb(Port + 4, mcr.raw);
|
||||
|
||||
/* Enable interrupts on receive */
|
||||
ier.InterruptOnReceive = 1;
|
||||
outb(Port + 1, ier.raw);
|
||||
RegisterInterruptHandler(3, UartCOM24);
|
||||
RegisterInterruptHandler(4, UartCOM13);
|
||||
|
||||
LCS;
|
||||
KernelPrint("Port %#X initialized", Port);
|
||||
return true;
|
||||
}
|
||||
|
||||
int DetectUART()
|
||||
{
|
||||
uart.com1 = inb(COM1) != 0xFF ? true : false;
|
||||
uart.com2 = inb(COM2) != 0xFF ? true : false;
|
||||
uart.com3 = inb(COM3) != 0xFF ? true : false;
|
||||
uart.com4 = inb(COM4) != 0xFF ? true : false;
|
||||
uart.com5 = inb(COM5) != 0xFF ? true : false;
|
||||
uart.com6 = inb(COM6) != 0xFF ? true : false;
|
||||
uart.com7 = inb(COM7) != 0xFF ? true : false;
|
||||
uart.com8 = inb(COM8) != 0xFF ? true : false;
|
||||
|
||||
uart.lpt1 = inb(LPT1) != 0xFF ? true : false;
|
||||
uart.lpt2 = inb(LPT2) != 0xFF ? true : false;
|
||||
uart.lpt3 = inb(LPT3) != 0xFF ? true : false;
|
||||
|
||||
if (uart.com1 == true)
|
||||
if (InitializePort(COM1) == false)
|
||||
uart.com1 = false;
|
||||
|
||||
if (uart.com2 == true)
|
||||
if (InitializePort(COM2) == false)
|
||||
uart.com1 = false;
|
||||
|
||||
if (uart.com3 == true)
|
||||
if (InitializePort(COM3) == false)
|
||||
uart.com1 = false;
|
||||
|
||||
if (uart.com4 == true)
|
||||
if (InitializePort(COM4) == false)
|
||||
uart.com1 = false;
|
||||
|
||||
if (uart.com5 == true)
|
||||
if (InitializePort(COM5) == false)
|
||||
uart.com1 = false;
|
||||
|
||||
if (uart.com6 == true)
|
||||
if (InitializePort(COM6) == false)
|
||||
uart.com1 = false;
|
||||
|
||||
if (uart.com7 == true)
|
||||
if (InitializePort(COM7) == false)
|
||||
uart.com1 = false;
|
||||
|
||||
if (uart.com8 == true)
|
||||
if (InitializePort(COM8) == false)
|
||||
uart.com1 = false;
|
||||
|
||||
if (uart.lpt1 == true)
|
||||
KernelPrint("LPT1 is present");
|
||||
|
||||
if (uart.lpt2 == true)
|
||||
KernelPrint("LPT2 is present");
|
||||
|
||||
if (uart.lpt3 == true)
|
||||
KernelPrint("LPT3 is present");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// static int once = 0;
|
||||
// static uint8_t com4 = 0xFF;
|
||||
// if (!once++)
|
||||
// com4 = inb(0x2E8);
|
||||
// if (com4 == 0xFF)
|
||||
// CPU::Halt(true);
|
||||
// char UserInputBuffer[256]{'\0'};
|
||||
// int BackSpaceLimit = 0;
|
||||
// while (true)
|
||||
// {
|
||||
// while ((inb(0x2E8 + 5) & 1) == 0)
|
||||
// CPU::Pause();
|
||||
// char key = inb(0x2E8);
|
||||
// // debug("key: %d", key);
|
||||
// if (key == '\x7f') /* Backspace (DEL) */
|
||||
// {
|
||||
// if (BackSpaceLimit <= 0)
|
||||
// continue;
|
||||
// char keyBuf[5] = {'\b', '\x1b', '[', 'K', '\0'};
|
||||
// ExPrint(keyBuf);
|
||||
// backspace(UserInputBuffer);
|
||||
// BackSpaceLimit--;
|
||||
// continue;
|
||||
// }
|
||||
// else if (key == '\x0d') /* Enter (CR) */
|
||||
// {
|
||||
// UserInput(UserInputBuffer);
|
||||
// BackSpaceLimit = 0;
|
||||
// UserInputBuffer[0] = '\0';
|
||||
// continue;
|
||||
// }
|
||||
// else if (key == '\x1b') /* Escape */
|
||||
// {
|
||||
// char tmp[16]{'\0'};
|
||||
// append(tmp, key);
|
||||
// while ((inb(0x2E8 + 5) & 1) == 0)
|
||||
// CPU::Pause();
|
||||
// char key = inb(0x2E8);
|
||||
// append(tmp, key);
|
||||
// if (key == '[')
|
||||
// {
|
||||
// // 27 91
|
||||
// // < 68
|
||||
// // > 67
|
||||
// // down 66
|
||||
// // up 65
|
||||
// while ((inb(0x2E8 + 5) & 1) == 0)
|
||||
// CPU::Pause();
|
||||
// key = inb(0x2E8);
|
||||
// append(tmp, key);
|
||||
// switch (key)
|
||||
// {
|
||||
// case 'A':
|
||||
// key = KEY_D_UP;
|
||||
// break;
|
||||
// case 'B':
|
||||
// key = KEY_D_DOWN;
|
||||
// break;
|
||||
// case 'C':
|
||||
// key = KEY_D_RIGHT;
|
||||
// break;
|
||||
// case 'D':
|
||||
// key = KEY_D_LEFT;
|
||||
// break;
|
||||
// default:
|
||||
// {
|
||||
// for (size_t i = 0; i < strlen(tmp); i++)
|
||||
// {
|
||||
// if ((int)sizeof(UserInputBuffer) <= BackSpaceLimit)
|
||||
// continue;
|
||||
// append(UserInputBuffer, tmp[i]);
|
||||
// BackSpaceLimit++;
|
||||
// char keyBuf[2] = {(char)tmp[i], '\0'};
|
||||
// ExPrint(keyBuf);
|
||||
// }
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
// ArrowInput(key);
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if ((int)sizeof(UserInputBuffer) <= BackSpaceLimit)
|
||||
// continue;
|
||||
// append(UserInputBuffer, key);
|
||||
// BackSpaceLimit++;
|
||||
// char keyBuf[2] = {(char)key, '\0'};
|
||||
// ExPrint(keyBuf);
|
||||
// }
|
@ -1,21 +1,14 @@
|
||||
# Config file
|
||||
include ../../Makefile.conf
|
||||
|
||||
FILENAME = libkernel.so
|
||||
|
||||
CC = ../../$(COMPILER_PATH)/$(COMPILER_ARCH)gcc
|
||||
CPP = ../../$(COMPILER_PATH)/$(COMPILER_ARCH)g++
|
||||
LD = ../../$(COMPILER_PATH)/$(COMPILER_ARCH)ld
|
||||
AS = ../../$(COMPILER_PATH)/$(COMPILER_ARCH)as
|
||||
AR = ../../$(COMPILER_PATH)/$(COMPILER_ARCH)ar
|
||||
default:
|
||||
$(error Do not run this Makefile directly!)
|
||||
|
||||
S_SOURCES = $(shell find ./ -type f -name '*.S' -not -path "./crt/*")
|
||||
C_SOURCES = $(shell find ./ -type f -name '*.c' -not -path "./crt/*")
|
||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp' -not -path "./crt/*")
|
||||
HEADERS = $(sort $(dir $(wildcard ../include/*)))
|
||||
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(ASM_SOURCES:.asm=.o) $(S_SOURCES:.S=.o) $(PSF_SOURCES:.psf=.o) $(BMP_SOURCES:.bmp=.o)
|
||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||
INCLUDE_DIR = ../include
|
||||
CXX_SOURCES = $(shell find ./ -type f -name '*.cpp' -not -path "./crt/*")
|
||||
HEADERS = $(sort $(dir $(wildcard $(INCLUDE_DIR)/*)))
|
||||
OBJ = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o) $(ASM_SOURCES:.asm=.o) $(S_SOURCES:.S=.o) $(PSF_SOURCES:.psf=.o) $(BMP_SOURCES:.bmp=.o)
|
||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su)
|
||||
|
||||
LDFLAGS := -fPIC -fPIE -pie -nostdlib -nodefaultlibs -nolibc \
|
||||
-zmax-page-size=0x1000 -Wl,-Map libkernel.map -shared
|
||||
@ -43,7 +36,15 @@ CFLAGS += -pipe -fno-builtin -fPIC
|
||||
|
||||
endif
|
||||
|
||||
CRT_CFLAGS := -fPIC -fPIE -pie -mno-red-zone -std=c++20 -I../include
|
||||
CRT_CFLAGS := -fPIC -fPIE -pie -std=c++20 -I$(INCLUDE_DIR)
|
||||
|
||||
ifeq ($(OSARCH), amd64)
|
||||
CRT_CFLAGS += -mno-red-zone
|
||||
else ifeq ($(OSARCH), i386)
|
||||
CRT_CFLAGS += -mno-red-zone
|
||||
else ifeq ($(OSARCH), aarch64)
|
||||
CRT_CFLAGS +=
|
||||
endif
|
||||
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -DDEBUG -ggdb3 -O0 -fdiagnostics-color=always -fstack-usage
|
||||
@ -60,12 +61,12 @@ endif
|
||||
endif
|
||||
|
||||
build: $(FILENAME)
|
||||
$(CPP) $(CRT_CFLAGS) -c crt/crt0.cpp -o dcrt0.o
|
||||
mv dcrt0.o ../out/dcrt0.o
|
||||
$(CXX) $(CRT_CFLAGS) -c crt/crt0.cpp -o dcrt0.o
|
||||
mv dcrt0.o $(OUTPUT_DIR)dcrt0.o
|
||||
|
||||
$(FILENAME): $(OBJ)
|
||||
$(info Linking $@)
|
||||
$(CC) $(LDFLAGS) $(OBJ) -o ../out/$(FILENAME)
|
||||
$(CC) $(LDFLAGS) $(OBJ) -o $(OUTPUT_DIR)$(FILENAME)
|
||||
|
||||
%.o: %.c $(HEADERS)
|
||||
$(info Compiling $<)
|
||||
@ -73,7 +74,7 @@ $(FILENAME): $(OBJ)
|
||||
|
||||
%.o: %.cpp $(HEADERS)
|
||||
$(info Compiling $<)
|
||||
$(CPP) $(CFLAGS) $(WARNCFLAG) -std=c++20 -fexceptions -c $< -o $@
|
||||
$(CXX) $(CFLAGS) $(WARNCFLAG) -std=c++20 -fexceptions -c $< -o $@
|
||||
|
||||
%.o: %.S
|
||||
$(info Compiling $<)
|
||||
|
@ -73,7 +73,11 @@ DefineFunction(void, KernelPrint, const char *format, ...)
|
||||
{
|
||||
__builtin_va_list args;
|
||||
__builtin_va_start(args, format);
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
__KernelPrint(DriverID, (long)format, (long)args);
|
||||
#elif defined(__aarch64__)
|
||||
__KernelPrint(DriverID, (long)format, (long)__builtin_va_arg(args, void *));
|
||||
#endif
|
||||
__builtin_va_end(args);
|
||||
}
|
||||
|
||||
@ -81,7 +85,11 @@ DefineFunction(void, KernelLog, const char *format, ...)
|
||||
{
|
||||
__builtin_va_list args;
|
||||
__builtin_va_start(args, format);
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
__KernelLog(DriverID, (long)format, (long)args);
|
||||
#elif defined(__aarch64__)
|
||||
__KernelLog(DriverID, (long)format, (long)__builtin_va_arg(args, void *));
|
||||
#endif
|
||||
__builtin_va_end(args);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
build:
|
||||
make -C example build
|
||||
make -C vmware build
|
||||
MAKE_TARGETS := build clean
|
||||
DIRECTORIES := $(sort $(dir $(wildcard ./*/)))
|
||||
|
||||
clean:
|
||||
make -C example clean
|
||||
make -C vmware clean
|
||||
.PHONY: $(MAKE_TARGETS) $(DIRECTORIES)
|
||||
|
||||
$(MAKE_TARGETS): $(DIRECTORIES)
|
||||
|
||||
$(DIRECTORIES):
|
||||
$(MAKE) -C $@ $(MAKECMDGOALS)
|
||||
|
@ -1,22 +1,35 @@
|
||||
# Config files
|
||||
include ../../../Makefile.conf
|
||||
include ../../config.mk
|
||||
default:
|
||||
$(error Do not run this Makefile directly!)
|
||||
|
||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||
CXX_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
||||
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
|
||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||
OBJ = $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
|
||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CXX_SOURCES:.cpp=.su)
|
||||
|
||||
FILENAME = example.drv
|
||||
FILENAME = $(notdir $(shell pwd)).drv
|
||||
|
||||
build: $(FILENAME)
|
||||
mv $(FILENAME) ../../out/$(FILENAME)
|
||||
mv $(FILENAME) $(OUTPUT_DIR)$(FILENAME)
|
||||
|
||||
$(FILENAME): $(OBJ)
|
||||
$(info Linking $@)
|
||||
$(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@
|
||||
$(CC) $(DRIVER_LDFLAGS) $(OBJ) $(OUTPUT_DIR)dcrt0.o -L$(OUTPUT_DIR) -lkernel -o $@
|
||||
|
||||
WARNCFLAG = -Wall -Wextra
|
||||
|
||||
%.o: %.c $(HEADERS)
|
||||
$(info Compiling $<)
|
||||
$(CC) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
|
||||
|
||||
%.o: %.cpp $(HEADERS)
|
||||
$(info Compiling $<)
|
||||
$(CXX) $(DRIVER_CFLAGS) $(WARNCFLAG) -std=c++20 -fno-exceptions -fno-rtti -c $< -o $@
|
||||
|
||||
%.o: %.S
|
||||
$(info Compiling $<)
|
||||
$(AS) -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
||||
|
@ -66,15 +66,14 @@ int DriverProbe()
|
||||
* This function is to test if the driver is compatible
|
||||
* with the hardware.
|
||||
* Example: Like if there is a PCI device that the driver
|
||||
* is for, or a CPU feature that etc.
|
||||
* is for, or a CPU feature etc.
|
||||
*
|
||||
* Return 0 if the driver is compatible with the hardware.
|
||||
* Otherwise, return a value that is not 0.
|
||||
*
|
||||
* Note: In this function you cannot use variables that
|
||||
* have constructors or destructors. Before DriverEntry,
|
||||
* the constructors are called and after DriverFinalize,
|
||||
* the destructors are called.
|
||||
* the destructors.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
|
@ -1,22 +0,0 @@
|
||||
# Config files
|
||||
include ../../../Makefile.conf
|
||||
include ../../config.mk
|
||||
|
||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
||||
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
|
||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||
|
||||
FILENAME = vmware.drv
|
||||
|
||||
build: $(FILENAME)
|
||||
mv $(FILENAME) ../../out/$(FILENAME)
|
||||
|
||||
$(FILENAME): $(OBJ)
|
||||
$(info Linking $@)
|
||||
$(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@
|
||||
|
||||
clean:
|
||||
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
@ -1,878 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <driver.h>
|
||||
#include <errno.h>
|
||||
#include <fs.h>
|
||||
#include <input.h>
|
||||
#include <regs.h>
|
||||
#include <base.h>
|
||||
#include <aip.h>
|
||||
#include <io.h>
|
||||
|
||||
enum RPCMessages
|
||||
{
|
||||
MSG_OPEN,
|
||||
MSG_SENDSIZE,
|
||||
MSG_SENDPAYLOAD,
|
||||
MSG_RECVSIZE,
|
||||
MSG_RECVPAYLOAD,
|
||||
MSG_RECVSTATUS,
|
||||
MSG_CLOSE,
|
||||
};
|
||||
|
||||
enum RPCStatus
|
||||
{
|
||||
STATUS_SUCCESS = 0x1,
|
||||
STATUS_DORECV = 0x2,
|
||||
STATUS_CPT = 0x10,
|
||||
STATUS_HB = 0x80,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t ax;
|
||||
uint32_t magic;
|
||||
};
|
||||
union
|
||||
{
|
||||
uint32_t bx;
|
||||
size_t size;
|
||||
};
|
||||
union
|
||||
{
|
||||
uint32_t cx;
|
||||
uint16_t command;
|
||||
};
|
||||
union
|
||||
{
|
||||
uint32_t dx;
|
||||
uint16_t port;
|
||||
};
|
||||
uint32_t si;
|
||||
uint32_t di;
|
||||
} VMwareCommand;
|
||||
|
||||
#define VMWARE_MAGIC 0x564D5868
|
||||
|
||||
#define VMWARE_PORT 0x5658
|
||||
#define VMWARE_PORTHB 0x5659
|
||||
|
||||
#define VMWARE_HYPERVISOR_HB 0x00000000
|
||||
#define VMWARE_HYPERVISOR_OUT 0x00000001
|
||||
|
||||
#define CMD_GETVERSION 0xA
|
||||
#define CMD_MESSAGE 0x1E
|
||||
#define CMD_ABSPOINTER_DATA 0x27
|
||||
#define CMD_ABSPOINTER_STATUS 0x28
|
||||
#define CMD_ABSPOINTER_COMMAND 0x29
|
||||
|
||||
#define ABSPOINTER_ENABLE 0x45414552
|
||||
#define ABSPOINTER_RELATIVE 0xF5
|
||||
#define ABSPOINTER_ABSOLUTE 0x53424152
|
||||
|
||||
#define MESSAGE_RPCI 0x49435052
|
||||
#define MESSAGE_TCLO 0x4f4c4354
|
||||
|
||||
#define FLAG_COOKIE 0x80000000
|
||||
|
||||
#define ToMsg(x) ((x) << 16 | CMD_MESSAGE)
|
||||
#define HighWord(x) ((x & 0xFFFF0000) >> 16)
|
||||
|
||||
#define MESSAGE_HB_MSG 0
|
||||
|
||||
#define MESSAGE_OPEN_CHANNEL ToMsg(MSG_OPEN)
|
||||
#define MESSAGE_CLOSE_CHANNEL ToMsg(MSG_CLOSE)
|
||||
|
||||
#define MESSAGE_SEND_SIZE ToMsg(MSG_SENDSIZE)
|
||||
#define MESSAGE_SEND_PAYLOAD ToMsg(MSG_SENDPAYLOAD)
|
||||
|
||||
#define MESSAGE_RECV_SIZE ToMsg(MSG_RECVSIZE)
|
||||
#define MESSAGE_RECV_PAYLOAD ToMsg(MSG_RECVPAYLOAD)
|
||||
#define MESSAGE_RECV_STATUS ToMsg(MSG_RECVSTATUS)
|
||||
|
||||
#define VM_PORT(cmd, in_ebx, isi, idi, \
|
||||
flags, magic, \
|
||||
ax, bx, cx, dx, si, di) \
|
||||
__asm__ __volatile__("movw $0x5658, %%dx\n" \
|
||||
"inl %%dx, %%eax\n" \
|
||||
: "=a"(ax), \
|
||||
"=b"(bx), \
|
||||
"=c"(cx), \
|
||||
"=d"(dx), \
|
||||
"=S"(si), \
|
||||
"=D"(di) \
|
||||
: "a"(magic), \
|
||||
"b"(in_ebx), \
|
||||
"c"(cmd), \
|
||||
"d"(flags), \
|
||||
"S"(isi), \
|
||||
"D"(idi) : "memory")
|
||||
|
||||
#define VM_PORT_HB_OUT(cmd, in_ecx, isi, idi, \
|
||||
flags, magic, bp, \
|
||||
ax, bx, cx, dx, si, di) \
|
||||
__asm__ __volatile__("push %%rbp\n" \
|
||||
"mov %12, %%rbp\n" \
|
||||
"movw $0x5659, %%dx\n" \
|
||||
"rep outsb\n" \
|
||||
"pop %%rbp\n" \
|
||||
: "=a"(ax), \
|
||||
"=b"(bx), \
|
||||
"=c"(cx), \
|
||||
"=d"(dx), \
|
||||
"=S"(si), \
|
||||
"=D"(di) \
|
||||
: "a"(magic), \
|
||||
"b"(cmd), \
|
||||
"c"(in_ecx), \
|
||||
"d"(flags), \
|
||||
"S"(isi), \
|
||||
"D"(idi), \
|
||||
"r"(bp) : "memory", "cc")
|
||||
|
||||
#define VM_PORT_HB_IN(cmd, in_ecx, isi, idi, \
|
||||
flags, magic, bp, \
|
||||
ax, bx, cx, dx, si, di) \
|
||||
__asm__ __volatile__("push %%rbp\n" \
|
||||
"mov %12, %%rbp\n" \
|
||||
"movw $0x5659, %%dx\n" \
|
||||
"rep insb\n" \
|
||||
"pop %%rbp\n" \
|
||||
: "=a"(ax), \
|
||||
"=b"(bx), \
|
||||
"=c"(cx), \
|
||||
"=d"(dx), \
|
||||
"=S"(si), \
|
||||
"=D"(di) \
|
||||
: "a"(magic), \
|
||||
"b"(cmd), \
|
||||
"c"(in_ecx), \
|
||||
"d"(flags), \
|
||||
"S"(isi), \
|
||||
"D"(idi), \
|
||||
"r"(bp) : "memory", "cc")
|
||||
|
||||
/* TODO:
|
||||
- use vmcall or vmmcall instead of "out" and "in" if available
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int TCLOChannel;
|
||||
uint16_t ChannelID;
|
||||
uint32_t CookieHigh;
|
||||
uint32_t CookieLow;
|
||||
} ToolboxContext;
|
||||
|
||||
dev_t MouseDevID = -1;
|
||||
|
||||
int __strcmp(const char *l, const char *r)
|
||||
{
|
||||
for (; *l == *r && *l; l++, r++)
|
||||
;
|
||||
|
||||
return *(unsigned char *)l - *(unsigned char *)r;
|
||||
}
|
||||
|
||||
void __cpuid(uint32_t Function,
|
||||
uint32_t *eax, uint32_t *ebx,
|
||||
uint32_t *ecx, uint32_t *edx)
|
||||
{
|
||||
asmv("cpuid"
|
||||
: "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
|
||||
: "a"(Function));
|
||||
}
|
||||
|
||||
bool __CheckHypervisorBit()
|
||||
{
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
__cpuid(0x1, &eax, &ebx, &ecx, &edx);
|
||||
if (!(ecx & (1 << 31)))
|
||||
return false; /* Hypervisor not detected */
|
||||
return true;
|
||||
}
|
||||
|
||||
bool __VMwareBackdoorHypervisors()
|
||||
{
|
||||
const char hv[13] = {0};
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
__cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
|
||||
|
||||
*(uint32_t *)hv = ebx;
|
||||
*(uint32_t *)(hv + 4) = ecx;
|
||||
*(uint32_t *)(hv + 8) = edx;
|
||||
|
||||
if (__strcmp(hv, "VMwareVMware") != 0 &&
|
||||
__strcmp(hv, "KVMKVMKVM") != 0 &&
|
||||
__strcmp(hv, "TCGTCGTCGTCG") != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsVMwareBackdoorAvailable()
|
||||
{
|
||||
if (!__CheckHypervisorBit())
|
||||
return false;
|
||||
|
||||
if (!__VMwareBackdoorHypervisors())
|
||||
return false;
|
||||
|
||||
struct
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t ax;
|
||||
uint32_t magic;
|
||||
};
|
||||
union
|
||||
{
|
||||
uint32_t bx;
|
||||
size_t size;
|
||||
};
|
||||
union
|
||||
{
|
||||
uint32_t cx;
|
||||
uint16_t command;
|
||||
};
|
||||
union
|
||||
{
|
||||
uint32_t dx;
|
||||
uint16_t port;
|
||||
};
|
||||
uint32_t si;
|
||||
uint32_t di;
|
||||
} cmd;
|
||||
|
||||
cmd.si = cmd.di = 0;
|
||||
cmd.bx = ~0x564D5868;
|
||||
cmd.command = 0xA;
|
||||
cmd.magic = 0x564D5868;
|
||||
cmd.port = 0x5658;
|
||||
|
||||
asmv("in %%dx, %0"
|
||||
: "+a"(cmd.ax), "+b"(cmd.bx),
|
||||
"+c"(cmd.cx), "+d"(cmd.dx),
|
||||
"+S"(cmd.si), "+D"(cmd.di));
|
||||
|
||||
if (cmd.bx != 0x564D5868 ||
|
||||
cmd.ax == 0xFFFFFFFF)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int OpenMessageChannel(ToolboxContext *ctx, uint32_t Protocol)
|
||||
{
|
||||
uintptr_t ax, bx, cx, dx, si = 0, di = 0;
|
||||
|
||||
VM_PORT(MESSAGE_OPEN_CHANNEL,
|
||||
(Protocol | FLAG_COOKIE), si, di,
|
||||
0, VMWARE_MAGIC,
|
||||
ax, bx, cx, dx, si, di);
|
||||
|
||||
if ((HighWord(cx) & STATUS_SUCCESS) == 0)
|
||||
{
|
||||
KernelLog("Failed to open message channel %#lx", Protocol);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DebugLog("Opened message channel %d (Protocol: %#lx)",
|
||||
HighWord(dx), Protocol);
|
||||
ctx->ChannelID = (uint16_t)HighWord(dx);
|
||||
ctx->CookieHigh = si;
|
||||
ctx->CookieLow = di;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void MessageClose(ToolboxContext *ctx)
|
||||
{
|
||||
uintptr_t ax, bx, cx, dx,
|
||||
si = ctx->CookieHigh,
|
||||
di = ctx->CookieLow;
|
||||
|
||||
VM_PORT(MESSAGE_CLOSE_CHANNEL,
|
||||
0, si, di,
|
||||
ctx->ChannelID << 16,
|
||||
VMWARE_MAGIC,
|
||||
ax, bx, cx, dx, si, di);
|
||||
|
||||
DebugLog("Closed message channel %d", ctx->ChannelID);
|
||||
}
|
||||
|
||||
static uintptr_t MessageSendHB(ToolboxContext *ctx,
|
||||
const char *Message)
|
||||
{
|
||||
uintptr_t ax, bx, cx, dx,
|
||||
si = (uintptr_t)Message,
|
||||
di = ctx->CookieLow,
|
||||
bp = ctx->CookieHigh;
|
||||
|
||||
uint32_t ChannelID = ctx->ChannelID << 16;
|
||||
size_t Size = StringLength(Message);
|
||||
|
||||
VM_PORT_HB_OUT((STATUS_SUCCESS << 16) | MESSAGE_HB_MSG,
|
||||
Size, si, di,
|
||||
VMWARE_HYPERVISOR_HB | ChannelID | VMWARE_HYPERVISOR_OUT,
|
||||
VMWARE_MAGIC, bp,
|
||||
ax, bx, cx, dx, si, di);
|
||||
|
||||
return bx;
|
||||
}
|
||||
|
||||
static uintptr_t MessageSendLB(ToolboxContext *ctx,
|
||||
const char *Message)
|
||||
{
|
||||
uintptr_t ax, bx,
|
||||
cx = STATUS_SUCCESS << 16,
|
||||
dx, si, di;
|
||||
|
||||
size_t Size = StringLength(Message);
|
||||
while (Size &&
|
||||
(HighWord(cx) & STATUS_SUCCESS))
|
||||
{
|
||||
uint32_t TotalBytes = MIN((uint32_t)Size, (uint32_t)4);
|
||||
uint32_t Word = 0;
|
||||
MemoryCopy(&Word, Message, TotalBytes);
|
||||
Message += TotalBytes;
|
||||
|
||||
si = ctx->CookieHigh;
|
||||
di = ctx->CookieLow;
|
||||
|
||||
VM_PORT(MESSAGE_SEND_PAYLOAD,
|
||||
Word, si, di,
|
||||
ctx->ChannelID << 16,
|
||||
VMWARE_MAGIC,
|
||||
ax, bx, cx, dx, si, di);
|
||||
}
|
||||
|
||||
return cx;
|
||||
}
|
||||
|
||||
static uintptr_t MessageReceiveHB(ToolboxContext *ctx,
|
||||
char *Buffer,
|
||||
size_t BufferSize)
|
||||
{
|
||||
uintptr_t ax, bx, cx, dx,
|
||||
si = ctx->CookieHigh,
|
||||
di = (uintptr_t)Buffer,
|
||||
bp = ctx->CookieLow;
|
||||
|
||||
uint32_t ChannelID = ctx->ChannelID << 16;
|
||||
|
||||
VM_PORT_HB_IN((STATUS_SUCCESS << 16) | MESSAGE_HB_MSG,
|
||||
BufferSize, si, di,
|
||||
VMWARE_HYPERVISOR_HB | ChannelID | VMWARE_HYPERVISOR_OUT,
|
||||
VMWARE_MAGIC, bp,
|
||||
ax, bx, cx, dx, si, di);
|
||||
|
||||
return bx;
|
||||
}
|
||||
|
||||
static uintptr_t MessageReceiveLB(ToolboxContext *ctx,
|
||||
char *Buffer,
|
||||
size_t BufferSize)
|
||||
{
|
||||
uintptr_t ax, bx,
|
||||
cx = STATUS_SUCCESS << 16,
|
||||
dx, si, di;
|
||||
|
||||
while (BufferSize)
|
||||
{
|
||||
uint32_t TotalBytes = MIN((uint32_t)BufferSize, (uint32_t)4);
|
||||
|
||||
si = ctx->CookieHigh;
|
||||
di = ctx->CookieLow;
|
||||
|
||||
VM_PORT(MESSAGE_RECV_PAYLOAD,
|
||||
STATUS_SUCCESS, si, di,
|
||||
ctx->ChannelID << 16,
|
||||
VMWARE_MAGIC,
|
||||
ax, bx, cx, dx, si, di);
|
||||
|
||||
if ((HighWord(cx) & STATUS_SUCCESS) == 0)
|
||||
break;
|
||||
|
||||
MemoryCopy(Buffer, &bx, TotalBytes);
|
||||
Buffer += TotalBytes;
|
||||
BufferSize -= TotalBytes;
|
||||
}
|
||||
|
||||
return cx;
|
||||
}
|
||||
|
||||
static int MessageSend(ToolboxContext *ctx,
|
||||
const char *Message)
|
||||
{
|
||||
uintptr_t ax, bx, cx, dx, si, di;
|
||||
size_t Size = StringLength(Message);
|
||||
int Retries = 0;
|
||||
|
||||
while (Retries < 2)
|
||||
{
|
||||
Retries++;
|
||||
si = ctx->CookieHigh;
|
||||
di = ctx->CookieLow;
|
||||
|
||||
VM_PORT(MESSAGE_SEND_SIZE,
|
||||
Size, si, di,
|
||||
ctx->ChannelID << 16,
|
||||
VMWARE_MAGIC,
|
||||
ax, bx, cx, dx, si, di);
|
||||
|
||||
if ((HighWord(cx) & STATUS_SUCCESS) == 0)
|
||||
{
|
||||
KernelLog("Failed to send message size for \"%s\": %d",
|
||||
Message, cx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bool HighBand = (HighWord(cx) & STATUS_HB) != 0;
|
||||
if (HighBand)
|
||||
bx = MessageSendHB(ctx, Message);
|
||||
else
|
||||
bx = MessageSendLB(ctx, Message);
|
||||
|
||||
int status = HighWord(bx);
|
||||
|
||||
if ((status & STATUS_SUCCESS) != 0)
|
||||
{
|
||||
DebugLog("Message \"%s\" sent", Message);
|
||||
return 0;
|
||||
}
|
||||
else if ((status & STATUS_CPT) == 0)
|
||||
{
|
||||
KernelLog("Checkpoint occurred for message \"%s\"", Message);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
KernelLog("Failed to send message \"%s\": %#lx", Message, bx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int MessageReceive(ToolboxContext *ctx,
|
||||
char **Buffer,
|
||||
size_t *BufferSize)
|
||||
{
|
||||
uintptr_t ax, bx, cx, dx, si, di;
|
||||
int Retries = 0;
|
||||
|
||||
*Buffer = NULL;
|
||||
*BufferSize = 0;
|
||||
|
||||
char *ReplyBuf = NULL;
|
||||
size_t ReplyBufPages = 0;
|
||||
size_t ReplySize = 0;
|
||||
while (Retries < 2)
|
||||
{
|
||||
Retries++;
|
||||
si = ctx->CookieHigh;
|
||||
di = ctx->CookieLow;
|
||||
|
||||
VM_PORT(MESSAGE_RECV_SIZE,
|
||||
0, si, di,
|
||||
ctx->ChannelID << 16,
|
||||
VMWARE_MAGIC,
|
||||
ax, bx, cx, dx, si, di);
|
||||
|
||||
if ((HighWord(cx) & STATUS_SUCCESS) == 0)
|
||||
{
|
||||
KernelLog("Failed to receive message size: %d", cx);
|
||||
return -EINVAL;
|
||||
}
|
||||
else if ((HighWord(cx) & STATUS_DORECV) == 0)
|
||||
{
|
||||
DebugLog("No message to receive");
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
ReplySize = bx;
|
||||
|
||||
if (ReplyBuf != NULL)
|
||||
FreeMemory(ReplyBuf, ReplyBufPages);
|
||||
ReplyBufPages = ReplySize / 0x1000 + 1;
|
||||
ReplyBuf = AllocateMemory(ReplyBufPages);
|
||||
|
||||
bool HighBand = (HighWord(cx) & STATUS_HB) != 0;
|
||||
if (HighBand)
|
||||
bx = MessageReceiveHB(ctx, ReplyBuf, ReplySize);
|
||||
else
|
||||
bx = MessageReceiveLB(ctx, ReplyBuf, ReplySize);
|
||||
|
||||
if ((HighWord(bx) & STATUS_SUCCESS) == 0)
|
||||
{
|
||||
if ((HighWord(bx) & STATUS_CPT) == 0)
|
||||
{
|
||||
KernelLog("Checkpoint occurred for message payload");
|
||||
continue;
|
||||
}
|
||||
|
||||
KernelLog("Failed to receive message payload: %d", HighWord(bx));
|
||||
FreeMemory(ReplyBuf, ReplyBufPages);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ReplyBuf[ReplySize] = '\0';
|
||||
|
||||
si = ctx->CookieHigh;
|
||||
di = ctx->CookieLow;
|
||||
|
||||
VM_PORT(MESSAGE_RECV_STATUS,
|
||||
STATUS_SUCCESS, si, di,
|
||||
ctx->ChannelID << 16,
|
||||
VMWARE_MAGIC,
|
||||
ax, bx, cx, dx, si, di);
|
||||
|
||||
if ((HighWord(cx) & STATUS_SUCCESS) == 0)
|
||||
{
|
||||
if ((HighWord(cx) & STATUS_CPT) == 0)
|
||||
{
|
||||
KernelLog("Retrying message receive");
|
||||
continue;
|
||||
}
|
||||
|
||||
KernelLog("Failed to receive message status: %d", HighWord(cx));
|
||||
FreeMemory(ReplyBuf, ReplyBufPages);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (ReplyBuf == NULL)
|
||||
{
|
||||
KernelLog("Failed to receive message");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*Buffer = ReplyBuf;
|
||||
*BufferSize = ReplySize;
|
||||
DebugLog("Received message \"%s\"", ReplyBuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int SendRPCI(ToolboxContext *, const char *Request)
|
||||
{
|
||||
ToolboxContext rpci_ctx = {0};
|
||||
int status = OpenMessageChannel(&rpci_ctx, MESSAGE_RPCI);
|
||||
if (status < 0)
|
||||
{
|
||||
KernelLog("Failed to open RPCI channel: %d", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = MessageSend(&rpci_ctx, Request);
|
||||
if (status < 0)
|
||||
{
|
||||
KernelLog("Failed to send RPCI request: %d", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
MessageClose(&rpci_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MsgEqual(const char *haystack, const char *needle)
|
||||
{
|
||||
return strstr(haystack, needle) == haystack;
|
||||
}
|
||||
|
||||
static int DisplayGetSize(ToolboxContext *ctx)
|
||||
{
|
||||
if (ctx->TCLOChannel != -1)
|
||||
MessageClose(ctx);
|
||||
OpenMessageChannel(ctx, MESSAGE_TCLO);
|
||||
|
||||
char EmptyBuffer[256] = {'\0'};
|
||||
MessageSend(ctx, EmptyBuffer);
|
||||
|
||||
while (true)
|
||||
{
|
||||
/* FIXME: buf memory leak */
|
||||
char *buf;
|
||||
size_t len;
|
||||
|
||||
int status = MessageReceive(ctx, &buf, &len);
|
||||
if (status == -EAGAIN)
|
||||
{
|
||||
Sleep(1000);
|
||||
continue;
|
||||
}
|
||||
else if (status < 0)
|
||||
{
|
||||
KernelLog("Failed to receive message");
|
||||
return 1;
|
||||
}
|
||||
|
||||
buf[StringLength(buf)] = '\0';
|
||||
if (MsgEqual(buf, "reset"))
|
||||
{
|
||||
if (MessageSend(ctx, "OK ATR toolbox") < 0)
|
||||
return 1;
|
||||
}
|
||||
else if (MsgEqual(buf, "ping"))
|
||||
{
|
||||
if (MessageSend(ctx, "OK ") < 0)
|
||||
return 1;
|
||||
}
|
||||
else if (MsgEqual(buf, "Capabilities_Register"))
|
||||
{
|
||||
SendRPCI(ctx, "tools.capability.resolution_set 1");
|
||||
SendRPCI(ctx, "tools.capability.resolution_server toolbox 1");
|
||||
SendRPCI(ctx, "tools.capability.display_topology_set 1");
|
||||
SendRPCI(ctx, "tools.capability.color_depth_set 1");
|
||||
SendRPCI(ctx, "tools.capability.resolution_min 0 0");
|
||||
SendRPCI(ctx, "tools.capability.unity 1");
|
||||
|
||||
if (MessageSend(ctx, "OK ") < 0)
|
||||
return 1;
|
||||
}
|
||||
else if (MsgEqual(buf, "Resolution_Set"))
|
||||
{
|
||||
DebugLog("%s", buf);
|
||||
if (MessageSend(ctx, "OK ") < 0)
|
||||
return 1;
|
||||
MessageClose(ctx);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MessageSend(ctx, "ERROR Unknown command") < 0)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pid_t dst_id = -1;
|
||||
pid_t dst_pid = -1;
|
||||
ToolboxContext *tb_ctx = NULL;
|
||||
void DisplayScaleThread()
|
||||
{
|
||||
/* sizeof ToolboxContext */
|
||||
tb_ctx = AllocateMemory(1);
|
||||
Sleep(2000);
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (DisplayGetSize(tb_ctx) != 0)
|
||||
KernelLog("Failed to scale display");
|
||||
Sleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
void CommandSend(VMwareCommand *cmd)
|
||||
{
|
||||
cmd->magic = VMWARE_MAGIC;
|
||||
cmd->port = VMWARE_PORT;
|
||||
asm volatile("in %%dx, %0"
|
||||
: "+a"(cmd->ax), "+b"(cmd->bx),
|
||||
"+c"(cmd->cx), "+d"(cmd->dx),
|
||||
"+S"(cmd->si), "+D"(cmd->di));
|
||||
}
|
||||
|
||||
void Absolute()
|
||||
{
|
||||
VMwareCommand cmd = {0};
|
||||
|
||||
/* Enable */
|
||||
cmd.bx = ABSPOINTER_ENABLE;
|
||||
cmd.command = CMD_ABSPOINTER_COMMAND;
|
||||
CommandSend(&cmd);
|
||||
|
||||
/* Status */
|
||||
cmd.bx = 0;
|
||||
cmd.command = CMD_ABSPOINTER_STATUS;
|
||||
CommandSend(&cmd);
|
||||
|
||||
/* Read data (1) */
|
||||
cmd.bx = 1;
|
||||
cmd.command = CMD_ABSPOINTER_DATA;
|
||||
CommandSend(&cmd);
|
||||
|
||||
/* Enable absolute */
|
||||
cmd.bx = ABSPOINTER_ABSOLUTE;
|
||||
cmd.command = CMD_ABSPOINTER_COMMAND;
|
||||
CommandSend(&cmd);
|
||||
}
|
||||
|
||||
void Relative()
|
||||
{
|
||||
VMwareCommand cmd = {0};
|
||||
cmd.bx = ABSPOINTER_RELATIVE;
|
||||
cmd.command = CMD_ABSPOINTER_COMMAND;
|
||||
CommandSend(&cmd);
|
||||
}
|
||||
|
||||
InputReport ir = {0};
|
||||
void InterruptHandler(TrapFrame *)
|
||||
{
|
||||
uint8_t Data = inb(0x60);
|
||||
(void)Data;
|
||||
|
||||
VMwareCommand cmd = {0};
|
||||
cmd.bx = 0;
|
||||
cmd.command = CMD_ABSPOINTER_STATUS;
|
||||
CommandSend(&cmd);
|
||||
|
||||
if (cmd.ax == 0xFFFF0000)
|
||||
{
|
||||
KernelLog("VMware mouse is not connected?");
|
||||
Relative();
|
||||
Absolute();
|
||||
return;
|
||||
}
|
||||
|
||||
if ((cmd.ax & 0xFFFF) < 4)
|
||||
return;
|
||||
|
||||
cmd.bx = 4;
|
||||
cmd.command = CMD_ABSPOINTER_DATA;
|
||||
CommandSend(&cmd);
|
||||
|
||||
int Buttons = (cmd.ax & 0xFFFF);
|
||||
|
||||
/**
|
||||
* How should I handle this?
|
||||
* (cmd.[bx,cx] * Width) / 0xFFFF
|
||||
* Maybe TODO: Width and Height API?
|
||||
*/
|
||||
uintptr_t AbsoluteX = cmd.bx;
|
||||
uintptr_t AbsoluteY = cmd.cx;
|
||||
|
||||
ir.Type = INPUT_TYPE_MOUSE;
|
||||
ir.Device = MouseDevID;
|
||||
ir.Mouse.X = AbsoluteX;
|
||||
ir.Mouse.Y = AbsoluteY;
|
||||
ir.Mouse.Z = (int8_t)cmd.dx;
|
||||
ir.Mouse.Absolute = 1;
|
||||
ir.Mouse.LeftButton = Buttons & 0x20;
|
||||
ir.Mouse.RightButton = Buttons & 0x10;
|
||||
ir.Mouse.MiddleButton = Buttons & 0x08;
|
||||
// ir.Mouse.Button4 = 0x0;
|
||||
// ir.Mouse.Button5 = 0x0;
|
||||
// ir.Mouse.Button6 = 0x0;
|
||||
// ir.Mouse.Button7 = 0x0;
|
||||
// ir.Mouse.Button8 = 0x0;
|
||||
ReportInputEvent(&ir);
|
||||
}
|
||||
|
||||
int __fs_Ioctl(struct Inode *, unsigned long Request, void *)
|
||||
{
|
||||
switch (Request)
|
||||
{
|
||||
case 0x1:
|
||||
Relative();
|
||||
break;
|
||||
case 0x2:
|
||||
Absolute();
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct InodeOperations MouseOps = {
|
||||
.Ioctl = __fs_Ioctl,
|
||||
};
|
||||
|
||||
bool ToolboxSupported = false;
|
||||
int DriverEntry()
|
||||
{
|
||||
ToolboxContext tb_ctx = {0};
|
||||
/* Test if it's supported */
|
||||
int status = OpenMessageChannel(&tb_ctx, MESSAGE_TCLO);
|
||||
if (status == 0)
|
||||
{
|
||||
ToolboxSupported = true;
|
||||
MessageClose(&tb_ctx);
|
||||
dst_id = CreateKernelThread(0, "VMware Display Scale",
|
||||
(void *)DisplayScaleThread, NULL);
|
||||
dst_pid = GetCurrentProcess();
|
||||
}
|
||||
|
||||
PS2WriteCommand(PS2_CMD_ENABLE_PORT_2);
|
||||
PS2WriteCommand(PS2_CMD_READ_CONFIG);
|
||||
PS2_CONFIGURATION config = {.Raw = PS2ReadData()};
|
||||
config.Port2Interrupt = 1;
|
||||
PS2WriteCommand(PS2_CMD_WRITE_CONFIG);
|
||||
PS2WriteData(config.Raw);
|
||||
|
||||
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
||||
PS2WriteData(PS2_MOUSE_CMD_SET_DEFAULTS);
|
||||
PS2ReadData();
|
||||
|
||||
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
||||
PS2WriteData(PS2_MOUSE_CMD_ENABLE_DATA_REPORTING);
|
||||
PS2ReadData();
|
||||
Absolute();
|
||||
|
||||
/**
|
||||
* If we have another driver using the PS/2 mouse, we need to
|
||||
* override its interrupt handler.
|
||||
*/
|
||||
OverrideInterruptHandler(12, InterruptHandler);
|
||||
|
||||
MouseDevID = RegisterDevice(INPUT_TYPE_MOUSE, &MouseOps);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DriverFinal()
|
||||
{
|
||||
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
||||
PS2WriteData(PS2_MOUSE_CMD_DISABLE_DATA_REPORTING);
|
||||
|
||||
Relative();
|
||||
|
||||
UnregisterDevice(MouseDevID);
|
||||
|
||||
if (ToolboxSupported)
|
||||
{
|
||||
KillThread(dst_id, dst_pid, 0);
|
||||
if (tb_ctx->TCLOChannel != -1)
|
||||
MessageClose(tb_ctx);
|
||||
FreeMemory(tb_ctx, 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DriverPanic()
|
||||
{
|
||||
Relative();
|
||||
PS2WriteCommand(PS2_CMD_WRITE_NEXT_BYTE_TO_PS2_PORT_2_INPUT);
|
||||
PS2WriteData(PS2_MOUSE_CMD_DISABLE_DATA_REPORTING);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DriverProbe()
|
||||
{
|
||||
if (!IsVMwareBackdoorAvailable())
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DriverInfo("vmware",
|
||||
"VMware Tools Driver",
|
||||
"EnderIce2",
|
||||
0, 0, 1,
|
||||
"GPLv3");
|
@ -1,7 +1,9 @@
|
||||
build:
|
||||
make -C e1000 build
|
||||
make -C rtl8139 build
|
||||
MAKE_TARGETS := build clean
|
||||
DIRECTORIES := $(sort $(dir $(wildcard ./*/)))
|
||||
|
||||
clean:
|
||||
make -C e1000 clean
|
||||
make -C rtl8139 clean
|
||||
.PHONY: $(MAKE_TARGETS) $(DIRECTORIES)
|
||||
|
||||
$(MAKE_TARGETS): $(DIRECTORIES)
|
||||
|
||||
$(DIRECTORIES):
|
||||
$(MAKE) -C $@ $(MAKECMDGOALS)
|
||||
|
@ -1,22 +0,0 @@
|
||||
# Config files
|
||||
include ../../../Makefile.conf
|
||||
include ../../config.mk
|
||||
|
||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
||||
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
|
||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||
|
||||
FILENAME = e1000.drv
|
||||
|
||||
build: $(FILENAME)
|
||||
mv $(FILENAME) ../../out/$(FILENAME)
|
||||
|
||||
$(FILENAME): $(OBJ)
|
||||
$(info Linking $@)
|
||||
$(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@
|
||||
|
||||
clean:
|
||||
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
@ -1,512 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <netools.h>
|
||||
#include <errno.h>
|
||||
#include <regs.h>
|
||||
#include <base.h>
|
||||
#include <pci.h>
|
||||
#include <network.h>
|
||||
#include <io.h>
|
||||
|
||||
#include "e1000.hpp"
|
||||
|
||||
class E1000Device
|
||||
{
|
||||
private:
|
||||
PCIHeader0 *Header;
|
||||
uint16_t DeviceID;
|
||||
bool Initialized = false;
|
||||
|
||||
bool EEPROMAvailable;
|
||||
|
||||
struct BARData
|
||||
{
|
||||
uint8_t Type;
|
||||
uint16_t IOBase;
|
||||
uint64_t MemoryBase;
|
||||
} BAR;
|
||||
|
||||
#define E1000_NUM_RX_DESC 32
|
||||
#define E1000_NUM_TX_DESC 8
|
||||
RXDescriptor *RX[E1000_NUM_RX_DESC];
|
||||
TXDescriptor *TX[E1000_NUM_TX_DESC];
|
||||
|
||||
uint16_t RXCurrent;
|
||||
uint16_t TXCurrent;
|
||||
|
||||
const int BaseBufferSize = 8192;
|
||||
const int AdditionalBytes = 16;
|
||||
|
||||
uint32_t CurrentPacket;
|
||||
|
||||
void WriteCMD(uint16_t Address, uint32_t Value)
|
||||
{
|
||||
if (BAR.Type == 0)
|
||||
mmoutl((void *)(BAR.MemoryBase + Address), Value);
|
||||
else
|
||||
{
|
||||
outl(BAR.IOBase, Address);
|
||||
outl(BAR.IOBase + 4, Value);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ReadCMD(uint16_t Address)
|
||||
{
|
||||
if (BAR.Type == 0)
|
||||
return mminl((void *)(BAR.MemoryBase + Address));
|
||||
else
|
||||
{
|
||||
outl(BAR.IOBase, Address);
|
||||
return inl(BAR.IOBase + 0x4);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ReadEEPROM(uint8_t Address)
|
||||
{
|
||||
uint16_t Data = 0;
|
||||
uint32_t temp = 0;
|
||||
if (EEPROMAvailable)
|
||||
{
|
||||
WriteCMD(REG::EEPROM, (1) | ((uint32_t)(Address) << 8));
|
||||
while (!((temp = ReadCMD(REG::EEPROM)) & (1 << 4)))
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteCMD(REG::EEPROM, (1) | ((uint32_t)(Address) << 2));
|
||||
while (!((temp = ReadCMD(REG::EEPROM)) & (1 << 1)))
|
||||
;
|
||||
}
|
||||
Data = (uint16_t)((temp >> 16) & 0xFFFF);
|
||||
return Data;
|
||||
}
|
||||
|
||||
void InitializeRX()
|
||||
{
|
||||
DebugLog("Initializing RX...");
|
||||
uintptr_t Ptr = (uintptr_t)AllocateMemory(TO_PAGES(sizeof(RXDescriptor) *
|
||||
E1000_NUM_RX_DESC +
|
||||
AdditionalBytes));
|
||||
|
||||
for (int i = 0; i < E1000_NUM_RX_DESC; i++)
|
||||
{
|
||||
RX[i] = (RXDescriptor *)(Ptr + i * 16);
|
||||
RX[i]->Address = (uint64_t)AllocateMemory(TO_PAGES(BaseBufferSize + AdditionalBytes));
|
||||
RX[i]->Status = 0;
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wshift-count-overflow"
|
||||
|
||||
WriteCMD(REG::TXDESCLO, (uint32_t)(Ptr >> 32));
|
||||
WriteCMD(REG::TXDESCHI, (uint32_t)(Ptr & 0xFFFFFFFF));
|
||||
|
||||
WriteCMD(REG::RXDESCLO, (uint32_t)Ptr);
|
||||
WriteCMD(REG::RXDESCHI, 0);
|
||||
|
||||
WriteCMD(REG::RXDESCLEN, E1000_NUM_RX_DESC * 16);
|
||||
|
||||
WriteCMD(REG::RXDESCHEAD, 0);
|
||||
WriteCMD(REG::RXDESCTAIL, E1000_NUM_RX_DESC - 1);
|
||||
RXCurrent = 0;
|
||||
WriteCMD(REG::RCTRL, RCTL::EN | RCTL::SBP | RCTL::UPE |
|
||||
RCTL::MPE | RCTL::LBM_NONE |
|
||||
RTCL::RDMTS_HALF | RCTL::BAM |
|
||||
RCTL::SECRC | RCTL::BSIZE_8192);
|
||||
}
|
||||
|
||||
void InitializeTX()
|
||||
{
|
||||
DebugLog("Initializing TX...");
|
||||
uintptr_t Ptr = (uintptr_t)AllocateMemory(TO_PAGES(sizeof(TXDescriptor) *
|
||||
E1000_NUM_RX_DESC +
|
||||
AdditionalBytes));
|
||||
|
||||
for (short i = 0; i < E1000_NUM_TX_DESC; i++)
|
||||
{
|
||||
TX[i] = (TXDescriptor *)((uintptr_t)Ptr + i * 16);
|
||||
TX[i]->Address = 0;
|
||||
TX[i]->Command = 0;
|
||||
TX[i]->Status = TSTA::DD;
|
||||
}
|
||||
|
||||
WriteCMD(REG::TXDESCHI, (uint32_t)((uint64_t)Ptr >> 32));
|
||||
WriteCMD(REG::TXDESCLO, (uint32_t)((uint64_t)Ptr & 0xFFFFFFFF));
|
||||
|
||||
WriteCMD(REG::TXDESCLEN, E1000_NUM_TX_DESC * 16);
|
||||
|
||||
WriteCMD(REG::TXDESCHEAD, 0);
|
||||
WriteCMD(REG::TXDESCTAIL, 0);
|
||||
TXCurrent = 0;
|
||||
WriteCMD(REG::TCTRL, TCTL::EN_ | TCTL::PSP |
|
||||
(15 << TCTL::CT_SHIFT) |
|
||||
(64 << TCTL::COLD_SHIFT) |
|
||||
TCTL::RTLC);
|
||||
|
||||
WriteCMD(REG::TCTRL, 0b0110000000000111111000011111010);
|
||||
WriteCMD(REG::TIPG, 0x0060200A);
|
||||
}
|
||||
|
||||
public:
|
||||
dev_t ID;
|
||||
|
||||
bool IsInitialized() { return Initialized; }
|
||||
|
||||
size_t write(uint8_t *Buffer, size_t Size)
|
||||
{
|
||||
TX[TXCurrent]->Address = (uint64_t)Buffer;
|
||||
TX[TXCurrent]->Length = (uint16_t)Size;
|
||||
TX[TXCurrent]->Command = CMD::EOP | CMD::IFCS | CMD::RS;
|
||||
TX[TXCurrent]->Status = 0;
|
||||
uint16_t OldTXCurrent = TXCurrent;
|
||||
TXCurrent = (uint16_t)((TXCurrent + 1) % E1000_NUM_TX_DESC);
|
||||
WriteCMD(REG::TXDESCTAIL, TXCurrent);
|
||||
while (!(TX[OldTXCurrent]->Status & 0xFF))
|
||||
Yield();
|
||||
return Size;
|
||||
}
|
||||
|
||||
MediaAccessControl GetMAC()
|
||||
{
|
||||
MediaAccessControl mac;
|
||||
if (EEPROMAvailable)
|
||||
{
|
||||
uint32_t temp;
|
||||
temp = ReadEEPROM(0);
|
||||
mac.Address[0] = temp & 0xff;
|
||||
mac.Address[1] = (uint8_t)(temp >> 8);
|
||||
temp = ReadEEPROM(1);
|
||||
mac.Address[2] = temp & 0xff;
|
||||
mac.Address[3] = (uint8_t)(temp >> 8);
|
||||
temp = ReadEEPROM(2);
|
||||
mac.Address[4] = temp & 0xff;
|
||||
mac.Address[5] = (uint8_t)(temp >> 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t *BaseMac8 = (uint8_t *)(BAR.MemoryBase + 0x5400);
|
||||
uint32_t *BaseMac32 = (uint32_t *)(BAR.MemoryBase + 0x5400);
|
||||
if (BaseMac32[0] != 0)
|
||||
for (int i = 0; i < 6; i++)
|
||||
mac.Address[i] = BaseMac8[i];
|
||||
else
|
||||
{
|
||||
KernelLog("No MAC address found.");
|
||||
return MediaAccessControl();
|
||||
}
|
||||
}
|
||||
|
||||
return mac;
|
||||
}
|
||||
|
||||
int ioctl(NetIoctl req, void *arg)
|
||||
{
|
||||
switch (req)
|
||||
{
|
||||
case IOCTL_NET_GET_MAC:
|
||||
{
|
||||
MediaAccessControl mac = GetMAC();
|
||||
*((uint48_t *)arg) = mac.ToHex(); /* UNTESTED */
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void OnInterruptReceived(TrapFrame *)
|
||||
{
|
||||
WriteCMD(REG::IMASK, 0x1);
|
||||
uint32_t status = ReadCMD(0xC0);
|
||||
UNUSED(status);
|
||||
|
||||
while ((RX[RXCurrent]->Status & 0x1))
|
||||
{
|
||||
uint8_t *data = (uint8_t *)RX[RXCurrent]->Address;
|
||||
uint16_t dataSz = RX[RXCurrent]->Length;
|
||||
|
||||
// ReportNetworkPacket(ID, data, dataSz);
|
||||
/* FIXME: Implement */
|
||||
KernelLog("FIXME: Received packet");
|
||||
(void)data;
|
||||
(void)dataSz;
|
||||
|
||||
RX[RXCurrent]->Status = 0;
|
||||
uint16_t OldRXCurrent = RXCurrent;
|
||||
RXCurrent = (uint16_t)((RXCurrent + 1) % E1000_NUM_RX_DESC);
|
||||
WriteCMD(REG::RXDESCTAIL, OldRXCurrent);
|
||||
}
|
||||
}
|
||||
|
||||
void Panic()
|
||||
{
|
||||
WriteCMD(REG::IMASK, 0x00000000);
|
||||
WriteCMD(REG::ITR, 0x00000000);
|
||||
WriteCMD(REG::IAM, 0x00000000);
|
||||
}
|
||||
|
||||
E1000Device(PCIHeader0 *_Header, uint16_t _DeviceID)
|
||||
: Header(_Header),
|
||||
DeviceID(_DeviceID)
|
||||
{
|
||||
uint32_t PCIBAR0 = Header->BAR0;
|
||||
uint32_t PCIBAR1 = Header->BAR1;
|
||||
BAR.Type = PCIBAR0 & 1;
|
||||
BAR.IOBase = (uint16_t)(PCIBAR0 & (~3));
|
||||
BAR.MemoryBase = PCIBAR1 & (~15);
|
||||
|
||||
switch (DeviceID)
|
||||
{
|
||||
case 0x100E:
|
||||
{
|
||||
KernelLog("Found Intel 82540EM Gigabit Ethernet Controller.");
|
||||
|
||||
/* Detect EEPROM */
|
||||
WriteCMD(REG::EEPROM, 0x1);
|
||||
for (int i = 0; i < 1000 && !EEPROMAvailable; i++)
|
||||
if (ReadCMD(REG::EEPROM) & 0x10)
|
||||
EEPROMAvailable = true;
|
||||
else
|
||||
EEPROMAvailable = false;
|
||||
|
||||
if (!GetMAC().Valid())
|
||||
{
|
||||
KernelLog("Failed to get MAC");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Start link */
|
||||
uint32_t cmdret = ReadCMD(REG::CTRL);
|
||||
WriteCMD(REG::CTRL, cmdret | ECTRL::SLU);
|
||||
|
||||
for (int i = 0; i < 0x80; i++)
|
||||
WriteCMD((uint16_t)(0x5200 + i * 4), 0);
|
||||
|
||||
WriteCMD(REG::IMASK, 0x1F6DC);
|
||||
WriteCMD(REG::IMASK, 0xFF & ~4);
|
||||
ReadCMD(0xC0);
|
||||
|
||||
InitializeRX();
|
||||
InitializeTX();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
KernelLog("Unimplemented E1000 device.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
~E1000Device()
|
||||
{
|
||||
if (!Initialized)
|
||||
return;
|
||||
|
||||
switch (DeviceID)
|
||||
{
|
||||
case 0x100E:
|
||||
{
|
||||
// Clearing Enable bit in Receive Control Register
|
||||
uint32_t cmdret = ReadCMD(REG::RCTRL);
|
||||
WriteCMD(REG::RCTRL, cmdret & ~RCTL::EN);
|
||||
|
||||
// Masking Interrupt Mask, Interrupt Throttling Rate & Interrupt Auto-Mask
|
||||
WriteCMD(REG::IMASK, 0x00000000);
|
||||
WriteCMD(REG::ITR, 0x00000000);
|
||||
WriteCMD(REG::IAM, 0x00000000);
|
||||
|
||||
// Clearing SLU bit in Device Control Register
|
||||
cmdret = ReadCMD(REG::CTRL);
|
||||
WriteCMD(REG::CTRL, cmdret & ~ECTRL::SLU);
|
||||
|
||||
// Clear the Interrupt Cause Read register by reading it
|
||||
ReadCMD(REG::ICR);
|
||||
|
||||
// Powering down the device (?)
|
||||
WriteCMD(REG::CTRL, PCTRL::POWER_DOWN);
|
||||
/* TODO: Stop link; further testing required */
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
KernelLog("Unimplemented E1000 device.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
E1000Device *Drivers[4] = {nullptr};
|
||||
dev_t NetID[4] = {(dev_t)-1};
|
||||
|
||||
#define OIR(x) OIR_##x
|
||||
#define CREATE_OIR(x) \
|
||||
void OIR_##x(TrapFrame *f) { Drivers[x]->OnInterruptReceived(f); }
|
||||
|
||||
CREATE_OIR(0);
|
||||
CREATE_OIR(1);
|
||||
CREATE_OIR(2);
|
||||
CREATE_OIR(3);
|
||||
|
||||
int __fs_Open(struct Inode *, int, mode_t) { return 0; }
|
||||
int __fs_Close(struct Inode *) { return 0; }
|
||||
ssize_t __fs_Read(struct Inode *, void *, size_t, off_t) { return 0; }
|
||||
|
||||
ssize_t __fs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t)
|
||||
{
|
||||
return Drivers[NetID[Node->GetMinor()]]->write((uint8_t *)Buffer, Size);
|
||||
}
|
||||
|
||||
int __fs_Ioctl(struct Inode *Node, unsigned long Request, void *Argp)
|
||||
{
|
||||
return Drivers[NetID[Node->GetMinor()]]->ioctl((NetIoctl)Request, Argp);
|
||||
}
|
||||
|
||||
const struct InodeOperations NetOps = {
|
||||
.Lookup = nullptr,
|
||||
.Create = nullptr,
|
||||
.Remove = nullptr,
|
||||
.Rename = nullptr,
|
||||
.Read = __fs_Read,
|
||||
.Write = __fs_Write,
|
||||
.Truncate = nullptr,
|
||||
.Open = __fs_Open,
|
||||
.Close = __fs_Close,
|
||||
.Ioctl = __fs_Ioctl,
|
||||
.ReadDir = nullptr,
|
||||
.MkDir = nullptr,
|
||||
.RmDir = nullptr,
|
||||
.SymLink = nullptr,
|
||||
.ReadLink = nullptr,
|
||||
.Seek = nullptr,
|
||||
.Stat = nullptr,
|
||||
};
|
||||
|
||||
PCIArray *Devices;
|
||||
EXTERNC int cxx_Panic()
|
||||
{
|
||||
PCIArray *ctx = Devices;
|
||||
short Count = 0;
|
||||
while (ctx != nullptr)
|
||||
{
|
||||
if (Drivers[Count] != nullptr)
|
||||
Drivers[Count]->Panic();
|
||||
Count++;
|
||||
ctx = (PCIArray *)ctx->Next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXTERNC int cxx_Probe()
|
||||
{
|
||||
uint16_t VendorIDs[] = {0x8086, /* Intel */
|
||||
PCI_END};
|
||||
uint16_t DeviceIDs[] = {0x100E, /* 82540EM */
|
||||
0x100F, /* 82545EM */
|
||||
0x10D3, /* 82574L */
|
||||
0x10EA, /* I217-LM */
|
||||
0x153A, /* 82577LM */
|
||||
PCI_END};
|
||||
Devices = GetPCIDevices(VendorIDs, DeviceIDs);
|
||||
if (Devices == nullptr)
|
||||
{
|
||||
KernelLog("No E1000 device found.");
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXTERNC int cxx_Initialize()
|
||||
{
|
||||
PCIArray *ctx = Devices;
|
||||
size_t Count = 0;
|
||||
while (ctx != nullptr)
|
||||
{
|
||||
if (Count > sizeof(Drivers) / sizeof(E1000Device *))
|
||||
break;
|
||||
|
||||
InitializePCI(ctx->Device);
|
||||
|
||||
Drivers[Count] = new E1000Device((PCIHeader0 *)ctx->Device->Header,
|
||||
ctx->Device->Header->DeviceID);
|
||||
|
||||
if (Drivers[Count]->IsInitialized())
|
||||
{
|
||||
dev_t ret = RegisterDevice(NETWORK_TYPE_ETHERNET, &NetOps);
|
||||
NetID[Count] = ret;
|
||||
Drivers[Count]->ID = ret;
|
||||
|
||||
/* FIXME: bad code */
|
||||
switch (Count)
|
||||
{
|
||||
case 0:
|
||||
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(0));
|
||||
break;
|
||||
case 1:
|
||||
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(1));
|
||||
break;
|
||||
case 2:
|
||||
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(2));
|
||||
break;
|
||||
case 3:
|
||||
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(3));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Count++;
|
||||
}
|
||||
ctx = (PCIArray *)ctx->Next;
|
||||
}
|
||||
|
||||
if (Count == 0)
|
||||
{
|
||||
KernelLog("No valid E1000 device found.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXTERNC int cxx_Finalize()
|
||||
{
|
||||
PCIArray *ctx = Devices;
|
||||
size_t Count = 0;
|
||||
while (ctx != nullptr)
|
||||
{
|
||||
if (Count++ > sizeof(Drivers) / sizeof(E1000Device *))
|
||||
break;
|
||||
|
||||
delete Drivers[Count++];
|
||||
ctx->Device->Header->Command |= PCI_COMMAND_INTX_DISABLE;
|
||||
ctx = (PCIArray *)ctx->Next;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sizeof(NetID) / sizeof(dev_t); i++)
|
||||
{
|
||||
if (NetID[i] != (dev_t)-1)
|
||||
UnregisterDevice(NetID[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <base.h>
|
||||
|
||||
#include "e1000.hpp"
|
||||
|
||||
int DriverEntry() { return cxx_Initialize(); }
|
||||
int DriverFinal() { return cxx_Finalize(); }
|
||||
int DriverPanic() { return cxx_Panic(); }
|
||||
int DriverProbe() { return cxx_Probe(); }
|
||||
|
||||
DriverInfo("e1000",
|
||||
"Intel(R) PRO/1000 Network Driver",
|
||||
"EnderIce2",
|
||||
0, 0, 1,
|
||||
"GPLv3");
|
@ -1,22 +0,0 @@
|
||||
# Config files
|
||||
include ../../../Makefile.conf
|
||||
include ../../config.mk
|
||||
|
||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
||||
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
|
||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||
|
||||
FILENAME = rtl8139.drv
|
||||
|
||||
build: $(FILENAME)
|
||||
mv $(FILENAME) ../../out/$(FILENAME)
|
||||
|
||||
$(FILENAME): $(OBJ)
|
||||
$(info Linking $@)
|
||||
$(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@
|
||||
|
||||
clean:
|
||||
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <base.h>
|
||||
|
||||
#include "rtl8139.hpp"
|
||||
|
||||
int DriverEntry() { return cxx_Initialize(); }
|
||||
int DriverFinal() { return cxx_Finalize(); }
|
||||
int DriverPanic() { return cxx_Panic(); }
|
||||
int DriverProbe() { return cxx_Probe(); }
|
||||
|
||||
DriverInfo("rtl8139",
|
||||
"Realtek RTL8139 Network Driver",
|
||||
"EnderIce2",
|
||||
0, 0, 1,
|
||||
"GPLv3");
|
@ -1,325 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <netools.h>
|
||||
#include <errno.h>
|
||||
#include <regs.h>
|
||||
#include <base.h>
|
||||
#include <pci.h>
|
||||
#include <network.h>
|
||||
#include <io.h>
|
||||
|
||||
#include "rtl8139.hpp"
|
||||
|
||||
class RTL8139Device
|
||||
{
|
||||
private:
|
||||
PCIHeader0 *Header;
|
||||
bool Initialized = false;
|
||||
|
||||
struct BARData
|
||||
{
|
||||
uint8_t Type;
|
||||
uint16_t IOBase;
|
||||
uint64_t MemoryBase;
|
||||
} BAR;
|
||||
|
||||
const int BaseBufferSize = 8192;
|
||||
const int WRAPBytes = 1500;
|
||||
const int AdditionalBytes = 16;
|
||||
const int BufferSize = BaseBufferSize +
|
||||
WRAPBytes +
|
||||
AdditionalBytes;
|
||||
|
||||
uint8_t *RXBuffer = nullptr;
|
||||
int TXCurrent = 0;
|
||||
uint16_t CurrentPacket = 0;
|
||||
|
||||
uint8_t TSAD[4] = {0x20, 0x24, 0x28, 0x2C};
|
||||
uint8_t TSD[4] = {0x10, 0x14, 0x18, 0x1C};
|
||||
|
||||
public:
|
||||
dev_t ID;
|
||||
|
||||
bool IsInitialized() { return Initialized; }
|
||||
|
||||
size_t write(uint8_t *Buffer, size_t Size)
|
||||
{
|
||||
outl(TSAD[TXCurrent], (uint32_t)(reinterpret_cast<uint64_t>(Buffer)));
|
||||
outl(TSD[TXCurrent++], (uint32_t)Size);
|
||||
if (TXCurrent > 3)
|
||||
TXCurrent = 0;
|
||||
return Size;
|
||||
}
|
||||
|
||||
MediaAccessControl GetMAC()
|
||||
{
|
||||
return MediaAccessControl();
|
||||
}
|
||||
|
||||
int ioctl(NetIoctl req, void *)
|
||||
{
|
||||
switch (req)
|
||||
{
|
||||
case IOCTL_NET_GET_MAC:
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void OnInterruptReceived(TrapFrame *)
|
||||
{
|
||||
/* Acknowledge interrupt */
|
||||
uint16_t status = inw(RegISR);
|
||||
DebugLog("%#lx", status);
|
||||
|
||||
/* Read status */
|
||||
if (status & RecOK)
|
||||
{
|
||||
/* Get the current packet */
|
||||
uint16_t *data = (uint16_t *)(RXBuffer + CurrentPacket);
|
||||
uint16_t dataSz = *(data + 1);
|
||||
data += 2;
|
||||
|
||||
// ReportNetworkPacket(ID, data, dataSz);
|
||||
/* FIXME: Implement */
|
||||
KernelLog("FIXME: Received packet");
|
||||
(void)data;
|
||||
(void)dataSz;
|
||||
|
||||
/* Update CAPR */
|
||||
#define RX_READ_PTR_MASK (~0x3)
|
||||
CurrentPacket = (uint16_t)((CurrentPacket + dataSz + 4 + 3) & RX_READ_PTR_MASK);
|
||||
if (CurrentPacket > BufferSize)
|
||||
CurrentPacket -= uint16_t(BufferSize);
|
||||
outw(RegCAPR, CurrentPacket - 0x10);
|
||||
}
|
||||
|
||||
/* Clear interrupt */
|
||||
outw(RegISR, (RecOK | RecBad | SendOK | SendBad));
|
||||
}
|
||||
|
||||
void Panic()
|
||||
{
|
||||
}
|
||||
|
||||
RTL8139Device(PCIHeader0 *_Header)
|
||||
: Header(_Header)
|
||||
{
|
||||
uint32_t PCIBAR0 = Header->BAR0;
|
||||
uint32_t PCIBAR1 = Header->BAR1;
|
||||
BAR.Type = PCIBAR0 & 1;
|
||||
BAR.IOBase = (uint16_t)(PCIBAR0 & (~3));
|
||||
BAR.MemoryBase = PCIBAR1 & (~15);
|
||||
|
||||
RXBuffer = (uint8_t *)AllocateMemory(TO_PAGES(BufferSize));
|
||||
|
||||
/* Power on */
|
||||
outb(RegCONFIG1, 0x0);
|
||||
|
||||
/* Software Reset */
|
||||
outb(RegCMD, 0x10);
|
||||
while (inb(RegCMD) & 0x10)
|
||||
Yield();
|
||||
|
||||
/* Initialize receive buffer */
|
||||
outl(RegRBSTART, (uint32_t)(reinterpret_cast<uintptr_t>(RXBuffer)));
|
||||
|
||||
/* Configure interrupt mask register */
|
||||
outw(RegIMR, (RecOK | RecBad | SendOK | SendBad));
|
||||
outl(regRCR, (RcAB | RcAM | RcAPM | RcAAP) | RcWRAP);
|
||||
|
||||
/* Enable receive and transmit */
|
||||
outb(RegCMD, 0xC); /* 0xC = RE and TE bit */
|
||||
|
||||
uint32_t MAC1 = inl(RegMAC);
|
||||
uint16_t MAC2 = inw(RegMAR);
|
||||
MediaAccessControl mac = {
|
||||
mac.Address[0] = (uint8_t)MAC1,
|
||||
mac.Address[1] = (uint8_t)(MAC1 >> 8),
|
||||
mac.Address[2] = (uint8_t)(MAC1 >> 16),
|
||||
mac.Address[3] = (uint8_t)(MAC1 >> 24),
|
||||
mac.Address[4] = (uint8_t)MAC2,
|
||||
mac.Address[5] = (uint8_t)(MAC2 >> 8)};
|
||||
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
~RTL8139Device()
|
||||
{
|
||||
if (!Initialized)
|
||||
return;
|
||||
|
||||
/* FIXME: Shutdown code */
|
||||
}
|
||||
};
|
||||
|
||||
RTL8139Device *Drivers[4] = {nullptr};
|
||||
dev_t NetID[4] = {(dev_t)-1};
|
||||
|
||||
#define OIR(x) OIR_##x
|
||||
#define CREATE_OIR(x) \
|
||||
void OIR_##x(TrapFrame *f) { Drivers[x]->OnInterruptReceived(f); }
|
||||
|
||||
CREATE_OIR(0);
|
||||
CREATE_OIR(1);
|
||||
CREATE_OIR(2);
|
||||
CREATE_OIR(3);
|
||||
|
||||
int __fs_Open(struct Inode *, int, mode_t) { return 0; }
|
||||
int __fs_Close(struct Inode *) { return 0; }
|
||||
ssize_t __fs_Read(struct Inode *, void *, size_t, off_t) { return 0; }
|
||||
|
||||
ssize_t __fs_Write(struct Inode *Node, const void *Buffer, size_t Size, off_t)
|
||||
{
|
||||
return Drivers[NetID[Node->GetMinor()]]->write((uint8_t *)Buffer, Size);
|
||||
}
|
||||
|
||||
int __fs_Ioctl(struct Inode *Node, unsigned long Request, void *Argp)
|
||||
{
|
||||
return Drivers[NetID[Node->GetMinor()]]->ioctl((NetIoctl)Request, Argp);
|
||||
}
|
||||
|
||||
const struct InodeOperations NetOps = {
|
||||
.Lookup = nullptr,
|
||||
.Create = nullptr,
|
||||
.Remove = nullptr,
|
||||
.Rename = nullptr,
|
||||
.Read = __fs_Read,
|
||||
.Write = __fs_Write,
|
||||
.Truncate = nullptr,
|
||||
.Open = __fs_Open,
|
||||
.Close = __fs_Close,
|
||||
.Ioctl = __fs_Ioctl,
|
||||
.ReadDir = nullptr,
|
||||
.MkDir = nullptr,
|
||||
.RmDir = nullptr,
|
||||
.SymLink = nullptr,
|
||||
.ReadLink = nullptr,
|
||||
.Seek = nullptr,
|
||||
.Stat = nullptr,
|
||||
};
|
||||
|
||||
PCIArray *Devices;
|
||||
EXTERNC int cxx_Panic()
|
||||
{
|
||||
PCIArray *ctx = Devices;
|
||||
short Count = 0;
|
||||
while (ctx != nullptr)
|
||||
{
|
||||
if (Drivers[Count] != nullptr)
|
||||
Drivers[Count]->Panic();
|
||||
Count++;
|
||||
ctx = (PCIArray *)ctx->Next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXTERNC int cxx_Probe()
|
||||
{
|
||||
uint16_t VendorIDs[] = {0x10EC, /* Realtek */
|
||||
PCI_END};
|
||||
uint16_t DeviceIDs[] = {0x8139, /* RTL8139 */
|
||||
PCI_END};
|
||||
Devices = GetPCIDevices(VendorIDs, DeviceIDs);
|
||||
if (Devices == nullptr)
|
||||
{
|
||||
KernelLog("No RTL8139 device found.");
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXTERNC int cxx_Initialize()
|
||||
{
|
||||
PCIArray *ctx = Devices;
|
||||
size_t Count = 0;
|
||||
while (ctx != nullptr)
|
||||
{
|
||||
if (Count > sizeof(Drivers) / sizeof(RTL8139Device *))
|
||||
break;
|
||||
|
||||
InitializePCI(ctx->Device);
|
||||
|
||||
Drivers[Count] = new RTL8139Device((PCIHeader0 *)ctx->Device->Header);
|
||||
|
||||
if (Drivers[Count]->IsInitialized())
|
||||
{
|
||||
dev_t ret = RegisterDevice(NETWORK_TYPE_ETHERNET, &NetOps);
|
||||
NetID[Count] = ret;
|
||||
Drivers[Count]->ID = ret;
|
||||
|
||||
/* FIXME: bad code */
|
||||
switch (Count)
|
||||
{
|
||||
case 0:
|
||||
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(0));
|
||||
break;
|
||||
case 1:
|
||||
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(1));
|
||||
break;
|
||||
case 2:
|
||||
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(2));
|
||||
break;
|
||||
case 3:
|
||||
RegisterInterruptHandler(iLine(ctx->Device), (void *)OIR(3));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Count++;
|
||||
}
|
||||
ctx = (PCIArray *)ctx->Next;
|
||||
}
|
||||
|
||||
if (Count == 0)
|
||||
{
|
||||
KernelLog("No valid RTL8139 device found.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
EXTERNC int cxx_Finalize()
|
||||
{
|
||||
PCIArray *ctx = Devices;
|
||||
size_t Count = 0;
|
||||
while (ctx != nullptr)
|
||||
{
|
||||
if (Count++ > sizeof(Drivers) / sizeof(RTL8139Device *))
|
||||
break;
|
||||
|
||||
delete Drivers[Count++];
|
||||
ctx->Device->Header->Command |= PCI_COMMAND_INTX_DISABLE;
|
||||
ctx = (PCIArray *)ctx->Next;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sizeof(NetID) / sizeof(dev_t); i++)
|
||||
{
|
||||
if (NetID[i] != (dev_t)-1)
|
||||
UnregisterDevice(NetID[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
build:
|
||||
make -C ahci build
|
||||
make -C ata build
|
||||
MAKE_TARGETS := build clean
|
||||
DIRECTORIES := $(sort $(dir $(wildcard ./*/)))
|
||||
|
||||
clean:
|
||||
make -C ahci clean
|
||||
make -C ata clean
|
||||
.PHONY: $(MAKE_TARGETS) $(DIRECTORIES)
|
||||
|
||||
$(MAKE_TARGETS): $(DIRECTORIES)
|
||||
|
||||
$(DIRECTORIES):
|
||||
$(MAKE) -C $@ $(MAKECMDGOALS)
|
||||
|
@ -1,22 +0,0 @@
|
||||
# Config files
|
||||
include ../../../Makefile.conf
|
||||
include ../../config.mk
|
||||
|
||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
||||
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
|
||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||
|
||||
FILENAME = ahci.drv
|
||||
|
||||
build: $(FILENAME)
|
||||
mv $(FILENAME) ../../out/$(FILENAME)
|
||||
|
||||
$(FILENAME): $(OBJ)
|
||||
$(info Linking $@)
|
||||
$(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@
|
||||
|
||||
clean:
|
||||
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
File diff suppressed because it is too large
Load Diff
@ -1,31 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <base.h>
|
||||
|
||||
#include "ahci.hpp"
|
||||
|
||||
int DriverEntry() { return cxx_Initialize(); }
|
||||
int DriverFinal() { return cxx_Finalize(); }
|
||||
int DriverPanic() { return cxx_Panic(); }
|
||||
int DriverProbe() { return cxx_Probe(); }
|
||||
|
||||
DriverInfo("ahci",
|
||||
"Advanced Host Controller Interface Driver",
|
||||
"EnderIce2",
|
||||
0, 0, 1,
|
||||
"GPLv3");
|
@ -1,22 +0,0 @@
|
||||
# Config files
|
||||
include ../../../Makefile.conf
|
||||
include ../../config.mk
|
||||
|
||||
S_SOURCES = $(shell find ./ -type f -name '*.S')
|
||||
C_SOURCES = $(shell find ./ -type f -name '*.c')
|
||||
CPP_SOURCES = $(shell find ./ -type f -name '*.cpp')
|
||||
HEADERS = $(sort $(dir $(wildcard ../../include/*)))
|
||||
OBJ = $(C_SOURCES:.c=.o) $(CPP_SOURCES:.cpp=.o) $(S_SOURCES:.S=.o)
|
||||
STACK_USAGE_OBJ = $(C_SOURCES:.c=.su) $(CPP_SOURCES:.cpp=.su)
|
||||
|
||||
FILENAME = ata.drv
|
||||
|
||||
build: $(FILENAME)
|
||||
mv $(FILENAME) ../../out/$(FILENAME)
|
||||
|
||||
$(FILENAME): $(OBJ)
|
||||
$(info Linking $@)
|
||||
$(CC) $(DRIVER_LDFLAGS) $(OBJ) ../../out/dcrt0.o -L../../out -lkernel -o $@
|
||||
|
||||
clean:
|
||||
rm -f file.map $(OBJ) $(STACK_USAGE_OBJ)
|
@ -1,76 +0,0 @@
|
||||
/*
|
||||
This file is part of Fennix Drivers.
|
||||
|
||||
Fennix Drivers is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Drivers is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Drivers. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <regs.h>
|
||||
#include <base.h>
|
||||
#include <io.h>
|
||||
|
||||
bool IsATAPresent()
|
||||
{
|
||||
outb(0x1F0 + 2, 0);
|
||||
outb(0x1F0 + 3, 0);
|
||||
outb(0x1F0 + 4, 0);
|
||||
outb(0x1F0 + 5, 0);
|
||||
outb(0x1F0 + 7, 0xEC);
|
||||
if (inb(0x1F0 + 7) == 0 || inb(0x1F0 + 1) != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MasterInterruptHandler(TrapFrame *)
|
||||
{
|
||||
}
|
||||
|
||||
void SlaveInterruptHandler(TrapFrame *)
|
||||
{
|
||||
}
|
||||
|
||||
int DriverEntry()
|
||||
{
|
||||
RegisterInterruptHandler(14, MasterInterruptHandler);
|
||||
RegisterInterruptHandler(15, SlaveInterruptHandler);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DriverFinal()
|
||||
{
|
||||
UnregisterInterruptHandler(14, MasterInterruptHandler);
|
||||
UnregisterInterruptHandler(15, SlaveInterruptHandler);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DriverPanic()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DriverProbe()
|
||||
{
|
||||
if (!IsATAPresent())
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DriverInfo("ata",
|
||||
"Advanced Technology Attachment Driver",
|
||||
"EnderIce2",
|
||||
0, 0, 1,
|
||||
"GPLv3");
|
14
Fennix Bootloader.code-workspace
Normal file
14
Fennix Bootloader.code-workspace
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "./Bootloader"
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"terminal.integrated.cwd": "../",
|
||||
"debug.allowBreakpointsEverywhere": true,
|
||||
"git.defaultBranchName": "master",
|
||||
"git.openRepositoryInParentFolders": "always",
|
||||
"C_Cpp.autoAddFileAssociations": false,
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user