commit cab7a75780ef06fd24bd444f8311b07003ae1dae Author: RaphProductions <81994075+RaphProductions@users.noreply.github.com> Date: Tue May 6 20:19:48 2025 +0200 first commit diff --git a/.cache/clangd/index/absvdi2.c.54DDD5ACC67061C6.idx b/.cache/clangd/index/absvdi2.c.54DDD5ACC67061C6.idx new file mode 100755 index 0000000..c7fe8a2 Binary files /dev/null and b/.cache/clangd/index/absvdi2.c.54DDD5ACC67061C6.idx differ diff --git a/.cache/clangd/index/absvsi2.c.DA3C3A3D9E67C194.idx b/.cache/clangd/index/absvsi2.c.DA3C3A3D9E67C194.idx new file mode 100755 index 0000000..3c8d786 Binary files /dev/null and b/.cache/clangd/index/absvsi2.c.DA3C3A3D9E67C194.idx differ diff --git a/.cache/clangd/index/absvti2.c.5F2C75A775CFB6CC.idx b/.cache/clangd/index/absvti2.c.5F2C75A775CFB6CC.idx new file mode 100755 index 0000000..f7da332 Binary files /dev/null and b/.cache/clangd/index/absvti2.c.5F2C75A775CFB6CC.idx differ diff --git a/.cache/clangd/index/adddf3.c.E12B9FA5FFF3A116.idx b/.cache/clangd/index/adddf3.c.E12B9FA5FFF3A116.idx new file mode 100755 index 0000000..5458c3b Binary files /dev/null and b/.cache/clangd/index/adddf3.c.E12B9FA5FFF3A116.idx differ diff --git a/.cache/clangd/index/addsf3.c.6A21188085DB5939.idx b/.cache/clangd/index/addsf3.c.6A21188085DB5939.idx new file mode 100755 index 0000000..81517c2 Binary files /dev/null and b/.cache/clangd/index/addsf3.c.6A21188085DB5939.idx differ diff --git a/.cache/clangd/index/addtf3.c.FFEE1EAA375AB63D.idx b/.cache/clangd/index/addtf3.c.FFEE1EAA375AB63D.idx new file mode 100755 index 0000000..406efa2 Binary files /dev/null and b/.cache/clangd/index/addtf3.c.FFEE1EAA375AB63D.idx differ diff --git a/.cache/clangd/index/addvdi3.c.264BD2D5F21DA659.idx b/.cache/clangd/index/addvdi3.c.264BD2D5F21DA659.idx new file mode 100755 index 0000000..a5a8a6b Binary files /dev/null and b/.cache/clangd/index/addvdi3.c.264BD2D5F21DA659.idx differ diff --git a/.cache/clangd/index/addvsi3.c.0CD1DD6CF6936A4C.idx b/.cache/clangd/index/addvsi3.c.0CD1DD6CF6936A4C.idx new file mode 100755 index 0000000..f6341b5 Binary files /dev/null and b/.cache/clangd/index/addvsi3.c.0CD1DD6CF6936A4C.idx differ diff --git a/.cache/clangd/index/addvti3.c.9D846B9BFCBFA897.idx b/.cache/clangd/index/addvti3.c.9D846B9BFCBFA897.idx new file mode 100755 index 0000000..ec6f6f6 Binary files /dev/null and b/.cache/clangd/index/addvti3.c.9D846B9BFCBFA897.idx differ diff --git a/.cache/clangd/index/ashldi3.c.6A223231E8170398.idx b/.cache/clangd/index/ashldi3.c.6A223231E8170398.idx new file mode 100755 index 0000000..513e79b Binary files /dev/null and b/.cache/clangd/index/ashldi3.c.6A223231E8170398.idx differ diff --git a/.cache/clangd/index/ashlti3.c.B32287C6D4D707E3.idx b/.cache/clangd/index/ashlti3.c.B32287C6D4D707E3.idx new file mode 100755 index 0000000..1f0a20a Binary files /dev/null and b/.cache/clangd/index/ashlti3.c.B32287C6D4D707E3.idx differ diff --git a/.cache/clangd/index/ashrdi3.c.F2CC32C875AE2BB1.idx b/.cache/clangd/index/ashrdi3.c.F2CC32C875AE2BB1.idx new file mode 100755 index 0000000..2488400 Binary files /dev/null and b/.cache/clangd/index/ashrdi3.c.F2CC32C875AE2BB1.idx differ diff --git a/.cache/clangd/index/ashrti3.c.547C99831A12A8F7.idx b/.cache/clangd/index/ashrti3.c.547C99831A12A8F7.idx new file mode 100755 index 0000000..603deee Binary files /dev/null and b/.cache/clangd/index/ashrti3.c.547C99831A12A8F7.idx differ diff --git a/.cache/clangd/index/bswapdi2.c.3266AE3B38272DC9.idx b/.cache/clangd/index/bswapdi2.c.3266AE3B38272DC9.idx new file mode 100755 index 0000000..eb8f186 Binary files /dev/null and b/.cache/clangd/index/bswapdi2.c.3266AE3B38272DC9.idx differ diff --git a/.cache/clangd/index/bswapsi2.c.6BA49B8A7292856C.idx b/.cache/clangd/index/bswapsi2.c.6BA49B8A7292856C.idx new file mode 100755 index 0000000..2661a2c Binary files /dev/null and b/.cache/clangd/index/bswapsi2.c.6BA49B8A7292856C.idx differ diff --git a/.cache/clangd/index/clzdi2.c.63FC64DE5751EBB0.idx b/.cache/clangd/index/clzdi2.c.63FC64DE5751EBB0.idx new file mode 100755 index 0000000..b772166 Binary files /dev/null and b/.cache/clangd/index/clzdi2.c.63FC64DE5751EBB0.idx differ diff --git a/.cache/clangd/index/clzsi2.c.A37F2C92E88FF3A8.idx b/.cache/clangd/index/clzsi2.c.A37F2C92E88FF3A8.idx new file mode 100755 index 0000000..43c4bbe Binary files /dev/null and b/.cache/clangd/index/clzsi2.c.A37F2C92E88FF3A8.idx differ diff --git a/.cache/clangd/index/clzti2.c.2A6BBD58CB8D70B2.idx b/.cache/clangd/index/clzti2.c.2A6BBD58CB8D70B2.idx new file mode 100755 index 0000000..67f6bf0 Binary files /dev/null and b/.cache/clangd/index/clzti2.c.2A6BBD58CB8D70B2.idx differ diff --git a/.cache/clangd/index/cmpdi2.c.FD632643048FD20D.idx b/.cache/clangd/index/cmpdi2.c.FD632643048FD20D.idx new file mode 100755 index 0000000..60ec9cd Binary files /dev/null and b/.cache/clangd/index/cmpdi2.c.FD632643048FD20D.idx differ diff --git a/.cache/clangd/index/cmpti2.c.CC8B1B5751C62B11.idx b/.cache/clangd/index/cmpti2.c.CC8B1B5751C62B11.idx new file mode 100755 index 0000000..4d79704 Binary files /dev/null and b/.cache/clangd/index/cmpti2.c.CC8B1B5751C62B11.idx differ diff --git a/.cache/clangd/index/comparedf2.c.D2B72062E5C44781.idx b/.cache/clangd/index/comparedf2.c.D2B72062E5C44781.idx new file mode 100755 index 0000000..bba3d12 Binary files /dev/null and b/.cache/clangd/index/comparedf2.c.D2B72062E5C44781.idx differ diff --git a/.cache/clangd/index/comparesf2.c.B9F43B600A274DEC.idx b/.cache/clangd/index/comparesf2.c.B9F43B600A274DEC.idx new file mode 100755 index 0000000..d7253cc Binary files /dev/null and b/.cache/clangd/index/comparesf2.c.B9F43B600A274DEC.idx differ diff --git a/.cache/clangd/index/comparetf2.c.F02E5BB1109C7844.idx b/.cache/clangd/index/comparetf2.c.F02E5BB1109C7844.idx new file mode 100755 index 0000000..cf4b4a8 Binary files /dev/null and b/.cache/clangd/index/comparetf2.c.F02E5BB1109C7844.idx differ diff --git a/.cache/clangd/index/cpuid.h.018C95D9E7A01A9C.idx b/.cache/clangd/index/cpuid.h.018C95D9E7A01A9C.idx new file mode 100755 index 0000000..8816d8a Binary files /dev/null and b/.cache/clangd/index/cpuid.h.018C95D9E7A01A9C.idx differ diff --git a/.cache/clangd/index/ctzdi2.c.12B949AE9BD59CAE.idx b/.cache/clangd/index/ctzdi2.c.12B949AE9BD59CAE.idx new file mode 100755 index 0000000..d2baa97 Binary files /dev/null and b/.cache/clangd/index/ctzdi2.c.12B949AE9BD59CAE.idx differ diff --git a/.cache/clangd/index/ctzsi2.c.D2E4645FDDB3AA58.idx b/.cache/clangd/index/ctzsi2.c.D2E4645FDDB3AA58.idx new file mode 100755 index 0000000..753bf00 Binary files /dev/null and b/.cache/clangd/index/ctzsi2.c.D2E4645FDDB3AA58.idx differ diff --git a/.cache/clangd/index/ctzti2.c.7FBB5DDBC32996D3.idx b/.cache/clangd/index/ctzti2.c.7FBB5DDBC32996D3.idx new file mode 100755 index 0000000..f59de5d Binary files /dev/null and b/.cache/clangd/index/ctzti2.c.7FBB5DDBC32996D3.idx differ diff --git a/.cache/clangd/index/divdc3.c.B02EEEA18AA404A6.idx b/.cache/clangd/index/divdc3.c.B02EEEA18AA404A6.idx new file mode 100755 index 0000000..5846b32 Binary files /dev/null and b/.cache/clangd/index/divdc3.c.B02EEEA18AA404A6.idx differ diff --git a/.cache/clangd/index/divdf3.c.7543317F59E8D2D2.idx b/.cache/clangd/index/divdf3.c.7543317F59E8D2D2.idx new file mode 100755 index 0000000..2dea0fe Binary files /dev/null and b/.cache/clangd/index/divdf3.c.7543317F59E8D2D2.idx differ diff --git a/.cache/clangd/index/divdi3.c.6BDA5150A6EB1D65.idx b/.cache/clangd/index/divdi3.c.6BDA5150A6EB1D65.idx new file mode 100755 index 0000000..a8718a0 Binary files /dev/null and b/.cache/clangd/index/divdi3.c.6BDA5150A6EB1D65.idx differ diff --git a/.cache/clangd/index/divmoddi4.c.82BCC30251D7E17A.idx b/.cache/clangd/index/divmoddi4.c.82BCC30251D7E17A.idx new file mode 100755 index 0000000..8bdd964 Binary files /dev/null and b/.cache/clangd/index/divmoddi4.c.82BCC30251D7E17A.idx differ diff --git a/.cache/clangd/index/divmodsi4.c.239A327BFFA5B8B6.idx b/.cache/clangd/index/divmodsi4.c.239A327BFFA5B8B6.idx new file mode 100755 index 0000000..822a31d Binary files /dev/null and b/.cache/clangd/index/divmodsi4.c.239A327BFFA5B8B6.idx differ diff --git a/.cache/clangd/index/divmodti4.c.00B492A2BA8BC858.idx b/.cache/clangd/index/divmodti4.c.00B492A2BA8BC858.idx new file mode 100755 index 0000000..1b404ee Binary files /dev/null and b/.cache/clangd/index/divmodti4.c.00B492A2BA8BC858.idx differ diff --git a/.cache/clangd/index/divsc3.c.BE681C46D41E1304.idx b/.cache/clangd/index/divsc3.c.BE681C46D41E1304.idx new file mode 100755 index 0000000..511f96e Binary files /dev/null and b/.cache/clangd/index/divsc3.c.BE681C46D41E1304.idx differ diff --git a/.cache/clangd/index/divsf3.c.C99FF64B7B096BFB.idx b/.cache/clangd/index/divsf3.c.C99FF64B7B096BFB.idx new file mode 100755 index 0000000..350e51c Binary files /dev/null and b/.cache/clangd/index/divsf3.c.C99FF64B7B096BFB.idx differ diff --git a/.cache/clangd/index/divsi3.c.DB00371C9235E262.idx b/.cache/clangd/index/divsi3.c.DB00371C9235E262.idx new file mode 100755 index 0000000..563725e Binary files /dev/null and b/.cache/clangd/index/divsi3.c.DB00371C9235E262.idx differ diff --git a/.cache/clangd/index/divtc3.c.A9DCC3E7BDEAF9BE.idx b/.cache/clangd/index/divtc3.c.A9DCC3E7BDEAF9BE.idx new file mode 100755 index 0000000..559b963 Binary files /dev/null and b/.cache/clangd/index/divtc3.c.A9DCC3E7BDEAF9BE.idx differ diff --git a/.cache/clangd/index/divtf3.c.B111A0CECA5D3035.idx b/.cache/clangd/index/divtf3.c.B111A0CECA5D3035.idx new file mode 100755 index 0000000..c5b59da Binary files /dev/null and b/.cache/clangd/index/divtf3.c.B111A0CECA5D3035.idx differ diff --git a/.cache/clangd/index/divti3.c.44FFFC33CBBD7E11.idx b/.cache/clangd/index/divti3.c.44FFFC33CBBD7E11.idx new file mode 100755 index 0000000..de09527 Binary files /dev/null and b/.cache/clangd/index/divti3.c.44FFFC33CBBD7E11.idx differ diff --git a/.cache/clangd/index/divxc3.c.905FFC7F29340495.idx b/.cache/clangd/index/divxc3.c.905FFC7F29340495.idx new file mode 100755 index 0000000..9a48c75 Binary files /dev/null and b/.cache/clangd/index/divxc3.c.905FFC7F29340495.idx differ diff --git a/.cache/clangd/index/extendbfsf2.c.751092311FFC84C9.idx b/.cache/clangd/index/extendbfsf2.c.751092311FFC84C9.idx new file mode 100755 index 0000000..bee12ec Binary files /dev/null and b/.cache/clangd/index/extendbfsf2.c.751092311FFC84C9.idx differ diff --git a/.cache/clangd/index/extenddftf2.c.7ED44045BFB3B238.idx b/.cache/clangd/index/extenddftf2.c.7ED44045BFB3B238.idx new file mode 100755 index 0000000..63b277a Binary files /dev/null and b/.cache/clangd/index/extenddftf2.c.7ED44045BFB3B238.idx differ diff --git a/.cache/clangd/index/extendhfsf2.c.03B8950D16847F43.idx b/.cache/clangd/index/extendhfsf2.c.03B8950D16847F43.idx new file mode 100755 index 0000000..56d863c Binary files /dev/null and b/.cache/clangd/index/extendhfsf2.c.03B8950D16847F43.idx differ diff --git a/.cache/clangd/index/extendhftf2.c.60BD20BBE0925EBD.idx b/.cache/clangd/index/extendhftf2.c.60BD20BBE0925EBD.idx new file mode 100755 index 0000000..fecae84 Binary files /dev/null and b/.cache/clangd/index/extendhftf2.c.60BD20BBE0925EBD.idx differ diff --git a/.cache/clangd/index/extendsfdf2.c.10FA9150AAA23E1B.idx b/.cache/clangd/index/extendsfdf2.c.10FA9150AAA23E1B.idx new file mode 100755 index 0000000..35411e7 Binary files /dev/null and b/.cache/clangd/index/extendsfdf2.c.10FA9150AAA23E1B.idx differ diff --git a/.cache/clangd/index/extendsftf2.c.FBF219AE01DC013A.idx b/.cache/clangd/index/extendsftf2.c.FBF219AE01DC013A.idx new file mode 100755 index 0000000..374c4f3 Binary files /dev/null and b/.cache/clangd/index/extendsftf2.c.FBF219AE01DC013A.idx differ diff --git a/.cache/clangd/index/extendxftf2.c.A63D2056E3253300.idx b/.cache/clangd/index/extendxftf2.c.A63D2056E3253300.idx new file mode 100755 index 0000000..e7f04b8 Binary files /dev/null and b/.cache/clangd/index/extendxftf2.c.A63D2056E3253300.idx differ diff --git a/.cache/clangd/index/ffsdi2.c.79C5DF073C096D49.idx b/.cache/clangd/index/ffsdi2.c.79C5DF073C096D49.idx new file mode 100755 index 0000000..178fef9 Binary files /dev/null and b/.cache/clangd/index/ffsdi2.c.79C5DF073C096D49.idx differ diff --git a/.cache/clangd/index/ffssi2.c.C81326D2B420BC3D.idx b/.cache/clangd/index/ffssi2.c.C81326D2B420BC3D.idx new file mode 100755 index 0000000..1f4e2a3 Binary files /dev/null and b/.cache/clangd/index/ffssi2.c.C81326D2B420BC3D.idx differ diff --git a/.cache/clangd/index/ffsti2.c.10AE75FA4F6916A1.idx b/.cache/clangd/index/ffsti2.c.10AE75FA4F6916A1.idx new file mode 100755 index 0000000..fa05ef0 Binary files /dev/null and b/.cache/clangd/index/ffsti2.c.10AE75FA4F6916A1.idx differ diff --git a/.cache/clangd/index/fixdfdi.c.BAC876D4848A9BE1.idx b/.cache/clangd/index/fixdfdi.c.BAC876D4848A9BE1.idx new file mode 100755 index 0000000..6d2f43b Binary files /dev/null and b/.cache/clangd/index/fixdfdi.c.BAC876D4848A9BE1.idx differ diff --git a/.cache/clangd/index/fixdfsi.c.905155CE468DF06C.idx b/.cache/clangd/index/fixdfsi.c.905155CE468DF06C.idx new file mode 100755 index 0000000..74a5bcb Binary files /dev/null and b/.cache/clangd/index/fixdfsi.c.905155CE468DF06C.idx differ diff --git a/.cache/clangd/index/fixdfti.c.1C431C9BAAE04900.idx b/.cache/clangd/index/fixdfti.c.1C431C9BAAE04900.idx new file mode 100755 index 0000000..2b3668b Binary files /dev/null and b/.cache/clangd/index/fixdfti.c.1C431C9BAAE04900.idx differ diff --git a/.cache/clangd/index/fixsfdi.c.8E8BDEC974895892.idx b/.cache/clangd/index/fixsfdi.c.8E8BDEC974895892.idx new file mode 100755 index 0000000..3354e8c Binary files /dev/null and b/.cache/clangd/index/fixsfdi.c.8E8BDEC974895892.idx differ diff --git a/.cache/clangd/index/fixsfsi.c.85D5AA2B5053F0FC.idx b/.cache/clangd/index/fixsfsi.c.85D5AA2B5053F0FC.idx new file mode 100755 index 0000000..0b53c88 Binary files /dev/null and b/.cache/clangd/index/fixsfsi.c.85D5AA2B5053F0FC.idx differ diff --git a/.cache/clangd/index/fixsfti.c.B78B16B87EA4D0FB.idx b/.cache/clangd/index/fixsfti.c.B78B16B87EA4D0FB.idx new file mode 100755 index 0000000..f363524 Binary files /dev/null and b/.cache/clangd/index/fixsfti.c.B78B16B87EA4D0FB.idx differ diff --git a/.cache/clangd/index/fixtfdi.c.2BE7D60DD19558AA.idx b/.cache/clangd/index/fixtfdi.c.2BE7D60DD19558AA.idx new file mode 100755 index 0000000..ce78064 Binary files /dev/null and b/.cache/clangd/index/fixtfdi.c.2BE7D60DD19558AA.idx differ diff --git a/.cache/clangd/index/fixtfsi.c.7F527BC145B84F62.idx b/.cache/clangd/index/fixtfsi.c.7F527BC145B84F62.idx new file mode 100755 index 0000000..3e98de6 Binary files /dev/null and b/.cache/clangd/index/fixtfsi.c.7F527BC145B84F62.idx differ diff --git a/.cache/clangd/index/fixtfti.c.11F9211E88441263.idx b/.cache/clangd/index/fixtfti.c.11F9211E88441263.idx new file mode 100755 index 0000000..3f27910 Binary files /dev/null and b/.cache/clangd/index/fixtfti.c.11F9211E88441263.idx differ diff --git a/.cache/clangd/index/fixunsdfdi.c.9DE83BF71DEA5831.idx b/.cache/clangd/index/fixunsdfdi.c.9DE83BF71DEA5831.idx new file mode 100755 index 0000000..86c7e90 Binary files /dev/null and b/.cache/clangd/index/fixunsdfdi.c.9DE83BF71DEA5831.idx differ diff --git a/.cache/clangd/index/fixunsdfsi.c.8F6C0FA84A784C45.idx b/.cache/clangd/index/fixunsdfsi.c.8F6C0FA84A784C45.idx new file mode 100755 index 0000000..4c91e93 Binary files /dev/null and b/.cache/clangd/index/fixunsdfsi.c.8F6C0FA84A784C45.idx differ diff --git a/.cache/clangd/index/fixunsdfti.c.EB752AFC1E65BD8E.idx b/.cache/clangd/index/fixunsdfti.c.EB752AFC1E65BD8E.idx new file mode 100755 index 0000000..af65750 Binary files /dev/null and b/.cache/clangd/index/fixunsdfti.c.EB752AFC1E65BD8E.idx differ diff --git a/.cache/clangd/index/fixunssfdi.c.FBEE38152258EB25.idx b/.cache/clangd/index/fixunssfdi.c.FBEE38152258EB25.idx new file mode 100755 index 0000000..0eb9ff1 Binary files /dev/null and b/.cache/clangd/index/fixunssfdi.c.FBEE38152258EB25.idx differ diff --git a/.cache/clangd/index/fixunssfsi.c.83C331E92668C640.idx b/.cache/clangd/index/fixunssfsi.c.83C331E92668C640.idx new file mode 100755 index 0000000..b2841ca Binary files /dev/null and b/.cache/clangd/index/fixunssfsi.c.83C331E92668C640.idx differ diff --git a/.cache/clangd/index/fixunssfti.c.3E5C1FE32DB42663.idx b/.cache/clangd/index/fixunssfti.c.3E5C1FE32DB42663.idx new file mode 100755 index 0000000..84653e5 Binary files /dev/null and b/.cache/clangd/index/fixunssfti.c.3E5C1FE32DB42663.idx differ diff --git a/.cache/clangd/index/fixunstfdi.c.7E0F2E026B8A0B3A.idx b/.cache/clangd/index/fixunstfdi.c.7E0F2E026B8A0B3A.idx new file mode 100755 index 0000000..73fd85a Binary files /dev/null and b/.cache/clangd/index/fixunstfdi.c.7E0F2E026B8A0B3A.idx differ diff --git a/.cache/clangd/index/fixunstfsi.c.56770C594F3637C0.idx b/.cache/clangd/index/fixunstfsi.c.56770C594F3637C0.idx new file mode 100755 index 0000000..ea31840 Binary files /dev/null and b/.cache/clangd/index/fixunstfsi.c.56770C594F3637C0.idx differ diff --git a/.cache/clangd/index/fixunstfti.c.38A7B9A9D0EA9E22.idx b/.cache/clangd/index/fixunstfti.c.38A7B9A9D0EA9E22.idx new file mode 100755 index 0000000..e19163f Binary files /dev/null and b/.cache/clangd/index/fixunstfti.c.38A7B9A9D0EA9E22.idx differ diff --git a/.cache/clangd/index/fixunsxfdi.c.9A84D715BA17B381.idx b/.cache/clangd/index/fixunsxfdi.c.9A84D715BA17B381.idx new file mode 100755 index 0000000..6f7d44c Binary files /dev/null and b/.cache/clangd/index/fixunsxfdi.c.9A84D715BA17B381.idx differ diff --git a/.cache/clangd/index/fixunsxfsi.c.64A80423C38553CD.idx b/.cache/clangd/index/fixunsxfsi.c.64A80423C38553CD.idx new file mode 100755 index 0000000..5ff535b Binary files /dev/null and b/.cache/clangd/index/fixunsxfsi.c.64A80423C38553CD.idx differ diff --git a/.cache/clangd/index/fixunsxfti.c.4F483535CE55842C.idx b/.cache/clangd/index/fixunsxfti.c.4F483535CE55842C.idx new file mode 100755 index 0000000..d5a8c52 Binary files /dev/null and b/.cache/clangd/index/fixunsxfti.c.4F483535CE55842C.idx differ diff --git a/.cache/clangd/index/fixxfdi.c.D44E12EDD8EBE9DD.idx b/.cache/clangd/index/fixxfdi.c.D44E12EDD8EBE9DD.idx new file mode 100755 index 0000000..bb980c2 Binary files /dev/null and b/.cache/clangd/index/fixxfdi.c.D44E12EDD8EBE9DD.idx differ diff --git a/.cache/clangd/index/fixxfti.c.0DDFB1146255EA26.idx b/.cache/clangd/index/fixxfti.c.0DDFB1146255EA26.idx new file mode 100755 index 0000000..01ec217 Binary files /dev/null and b/.cache/clangd/index/fixxfti.c.0DDFB1146255EA26.idx differ diff --git a/.cache/clangd/index/float.h.625403E5DB9249DE.idx b/.cache/clangd/index/float.h.625403E5DB9249DE.idx new file mode 100755 index 0000000..959aa10 Binary files /dev/null and b/.cache/clangd/index/float.h.625403E5DB9249DE.idx differ diff --git a/.cache/clangd/index/floatdidf.c.7CD83C80C431B262.idx b/.cache/clangd/index/floatdidf.c.7CD83C80C431B262.idx new file mode 100755 index 0000000..b4a42d0 Binary files /dev/null and b/.cache/clangd/index/floatdidf.c.7CD83C80C431B262.idx differ diff --git a/.cache/clangd/index/floatdisf.c.5406E7EBA96B77CA.idx b/.cache/clangd/index/floatdisf.c.5406E7EBA96B77CA.idx new file mode 100755 index 0000000..b2ee977 Binary files /dev/null and b/.cache/clangd/index/floatdisf.c.5406E7EBA96B77CA.idx differ diff --git a/.cache/clangd/index/floatditf.c.1801E16467493435.idx b/.cache/clangd/index/floatditf.c.1801E16467493435.idx new file mode 100755 index 0000000..46f42eb Binary files /dev/null and b/.cache/clangd/index/floatditf.c.1801E16467493435.idx differ diff --git a/.cache/clangd/index/floatdixf.c.6BB823913880BC0B.idx b/.cache/clangd/index/floatdixf.c.6BB823913880BC0B.idx new file mode 100755 index 0000000..e2fac1f Binary files /dev/null and b/.cache/clangd/index/floatdixf.c.6BB823913880BC0B.idx differ diff --git a/.cache/clangd/index/floatsidf.c.B60844C3948DAD9D.idx b/.cache/clangd/index/floatsidf.c.B60844C3948DAD9D.idx new file mode 100755 index 0000000..19f3849 Binary files /dev/null and b/.cache/clangd/index/floatsidf.c.B60844C3948DAD9D.idx differ diff --git a/.cache/clangd/index/floatsisf.c.C8A64A1A3FD185DE.idx b/.cache/clangd/index/floatsisf.c.C8A64A1A3FD185DE.idx new file mode 100755 index 0000000..9f2e899 Binary files /dev/null and b/.cache/clangd/index/floatsisf.c.C8A64A1A3FD185DE.idx differ diff --git a/.cache/clangd/index/floatsitf.c.202E46AB119C0745.idx b/.cache/clangd/index/floatsitf.c.202E46AB119C0745.idx new file mode 100755 index 0000000..6a5c4f8 Binary files /dev/null and b/.cache/clangd/index/floatsitf.c.202E46AB119C0745.idx differ diff --git a/.cache/clangd/index/floattidf.c.683CB983AA96D16A.idx b/.cache/clangd/index/floattidf.c.683CB983AA96D16A.idx new file mode 100755 index 0000000..79c25b1 Binary files /dev/null and b/.cache/clangd/index/floattidf.c.683CB983AA96D16A.idx differ diff --git a/.cache/clangd/index/floattisf.c.DCD4405D90466FEA.idx b/.cache/clangd/index/floattisf.c.DCD4405D90466FEA.idx new file mode 100755 index 0000000..c8b25ba Binary files /dev/null and b/.cache/clangd/index/floattisf.c.DCD4405D90466FEA.idx differ diff --git a/.cache/clangd/index/floattitf.c.4564D8E4DCE26A5A.idx b/.cache/clangd/index/floattitf.c.4564D8E4DCE26A5A.idx new file mode 100755 index 0000000..e01791f Binary files /dev/null and b/.cache/clangd/index/floattitf.c.4564D8E4DCE26A5A.idx differ diff --git a/.cache/clangd/index/floattixf.c.FD40D4766D0CDD61.idx b/.cache/clangd/index/floattixf.c.FD40D4766D0CDD61.idx new file mode 100755 index 0000000..3a3ca17 Binary files /dev/null and b/.cache/clangd/index/floattixf.c.FD40D4766D0CDD61.idx differ diff --git a/.cache/clangd/index/floatundidf.c.4B10E542023E51BA.idx b/.cache/clangd/index/floatundidf.c.4B10E542023E51BA.idx new file mode 100755 index 0000000..c922c6d Binary files /dev/null and b/.cache/clangd/index/floatundidf.c.4B10E542023E51BA.idx differ diff --git a/.cache/clangd/index/floatundisf.c.942666D3EDA3A6C0.idx b/.cache/clangd/index/floatundisf.c.942666D3EDA3A6C0.idx new file mode 100755 index 0000000..9cf6aa6 Binary files /dev/null and b/.cache/clangd/index/floatundisf.c.942666D3EDA3A6C0.idx differ diff --git a/.cache/clangd/index/floatunditf.c.BB11B91A5C07D1D0.idx b/.cache/clangd/index/floatunditf.c.BB11B91A5C07D1D0.idx new file mode 100755 index 0000000..dffc939 Binary files /dev/null and b/.cache/clangd/index/floatunditf.c.BB11B91A5C07D1D0.idx differ diff --git a/.cache/clangd/index/floatundixf.c.852B821C51C856A5.idx b/.cache/clangd/index/floatundixf.c.852B821C51C856A5.idx new file mode 100755 index 0000000..9532a89 Binary files /dev/null and b/.cache/clangd/index/floatundixf.c.852B821C51C856A5.idx differ diff --git a/.cache/clangd/index/floatunsidf.c.1C1C214B3A3590BE.idx b/.cache/clangd/index/floatunsidf.c.1C1C214B3A3590BE.idx new file mode 100755 index 0000000..eedffb4 Binary files /dev/null and b/.cache/clangd/index/floatunsidf.c.1C1C214B3A3590BE.idx differ diff --git a/.cache/clangd/index/floatunsisf.c.A55A87C94F7A1ADA.idx b/.cache/clangd/index/floatunsisf.c.A55A87C94F7A1ADA.idx new file mode 100755 index 0000000..4e19521 Binary files /dev/null and b/.cache/clangd/index/floatunsisf.c.A55A87C94F7A1ADA.idx differ diff --git a/.cache/clangd/index/floatunsitf.c.3F63253F59A658AC.idx b/.cache/clangd/index/floatunsitf.c.3F63253F59A658AC.idx new file mode 100755 index 0000000..05fedd0 Binary files /dev/null and b/.cache/clangd/index/floatunsitf.c.3F63253F59A658AC.idx differ diff --git a/.cache/clangd/index/floatuntidf.c.4D25F6F2BFB083CE.idx b/.cache/clangd/index/floatuntidf.c.4D25F6F2BFB083CE.idx new file mode 100755 index 0000000..0c77fc7 Binary files /dev/null and b/.cache/clangd/index/floatuntidf.c.4D25F6F2BFB083CE.idx differ diff --git a/.cache/clangd/index/floatuntisf.c.E8791E75DCCA8ABC.idx b/.cache/clangd/index/floatuntisf.c.E8791E75DCCA8ABC.idx new file mode 100755 index 0000000..41ba344 Binary files /dev/null and b/.cache/clangd/index/floatuntisf.c.E8791E75DCCA8ABC.idx differ diff --git a/.cache/clangd/index/floatuntitf.c.724E7F8ABECFDFC1.idx b/.cache/clangd/index/floatuntitf.c.724E7F8ABECFDFC1.idx new file mode 100755 index 0000000..4f8270f Binary files /dev/null and b/.cache/clangd/index/floatuntitf.c.724E7F8ABECFDFC1.idx differ diff --git a/.cache/clangd/index/floatuntixf.c.EE53F7D637B2A573.idx b/.cache/clangd/index/floatuntixf.c.EE53F7D637B2A573.idx new file mode 100755 index 0000000..229be0f Binary files /dev/null and b/.cache/clangd/index/floatuntixf.c.EE53F7D637B2A573.idx differ diff --git a/.cache/clangd/index/fp_mode.c.F75D5BE2C68790A2.idx b/.cache/clangd/index/fp_mode.c.F75D5BE2C68790A2.idx new file mode 100755 index 0000000..e74f1c3 Binary files /dev/null and b/.cache/clangd/index/fp_mode.c.F75D5BE2C68790A2.idx differ diff --git a/.cache/clangd/index/gdt.h.9C8AD8F8054C69EC.idx b/.cache/clangd/index/gdt.h.9C8AD8F8054C69EC.idx new file mode 100755 index 0000000..31a2bc1 Binary files /dev/null and b/.cache/clangd/index/gdt.h.9C8AD8F8054C69EC.idx differ diff --git a/.cache/clangd/index/idt.h.DDC5315D481C1E7B.idx b/.cache/clangd/index/idt.h.DDC5315D481C1E7B.idx new file mode 100755 index 0000000..f359c3e Binary files /dev/null and b/.cache/clangd/index/idt.h.DDC5315D481C1E7B.idx differ diff --git a/.cache/clangd/index/int_div_impl.inc.BD3EFF8675E59301.idx b/.cache/clangd/index/int_div_impl.inc.BD3EFF8675E59301.idx new file mode 100755 index 0000000..7726ad7 Binary files /dev/null and b/.cache/clangd/index/int_div_impl.inc.BD3EFF8675E59301.idx differ diff --git a/.cache/clangd/index/int_endianness.h.5C1E934C459A2C11.idx b/.cache/clangd/index/int_endianness.h.5C1E934C459A2C11.idx new file mode 100755 index 0000000..27945a8 Binary files /dev/null and b/.cache/clangd/index/int_endianness.h.5C1E934C459A2C11.idx differ diff --git a/.cache/clangd/index/int_lib.h.D23BF2CC468A26AE.idx b/.cache/clangd/index/int_lib.h.D23BF2CC468A26AE.idx new file mode 100755 index 0000000..9786a21 Binary files /dev/null and b/.cache/clangd/index/int_lib.h.D23BF2CC468A26AE.idx differ diff --git a/.cache/clangd/index/int_mulo_impl.inc.30AD609D66153543.idx b/.cache/clangd/index/int_mulo_impl.inc.30AD609D66153543.idx new file mode 100755 index 0000000..c82e429 Binary files /dev/null and b/.cache/clangd/index/int_mulo_impl.inc.30AD609D66153543.idx differ diff --git a/.cache/clangd/index/int_mulv_impl.inc.3446C6A8D30A8A95.idx b/.cache/clangd/index/int_mulv_impl.inc.3446C6A8D30A8A95.idx new file mode 100755 index 0000000..d913652 Binary files /dev/null and b/.cache/clangd/index/int_mulv_impl.inc.3446C6A8D30A8A95.idx differ diff --git a/.cache/clangd/index/int_types.h.C0E7CFD2C94C57DA.idx b/.cache/clangd/index/int_types.h.C0E7CFD2C94C57DA.idx new file mode 100755 index 0000000..209530c Binary files /dev/null and b/.cache/clangd/index/int_types.h.C0E7CFD2C94C57DA.idx differ diff --git a/.cache/clangd/index/int_util.c.CFBA7320024C669B.idx b/.cache/clangd/index/int_util.c.CFBA7320024C669B.idx new file mode 100755 index 0000000..0d007f2 Binary files /dev/null and b/.cache/clangd/index/int_util.c.CFBA7320024C669B.idx differ diff --git a/.cache/clangd/index/int_util.h.B784D7EB2DFF7796.idx b/.cache/clangd/index/int_util.h.B784D7EB2DFF7796.idx new file mode 100755 index 0000000..0661ea4 Binary files /dev/null and b/.cache/clangd/index/int_util.h.B784D7EB2DFF7796.idx differ diff --git a/.cache/clangd/index/io.h.2E7FA466828E882D.idx b/.cache/clangd/index/io.h.2E7FA466828E882D.idx new file mode 100755 index 0000000..1838e42 Binary files /dev/null and b/.cache/clangd/index/io.h.2E7FA466828E882D.idx differ diff --git a/.cache/clangd/index/limine.h.425D8D97D5109245.idx b/.cache/clangd/index/limine.h.425D8D97D5109245.idx new file mode 100755 index 0000000..1ca0194 Binary files /dev/null and b/.cache/clangd/index/limine.h.425D8D97D5109245.idx differ diff --git a/.cache/clangd/index/limits.h.BEAC231889042657.idx b/.cache/clangd/index/limits.h.BEAC231889042657.idx new file mode 100755 index 0000000..f4b812d Binary files /dev/null and b/.cache/clangd/index/limits.h.BEAC231889042657.idx differ diff --git a/.cache/clangd/index/log.h.E0E90EDA1BF56D22.idx b/.cache/clangd/index/log.h.E0E90EDA1BF56D22.idx new file mode 100755 index 0000000..e5c3e60 Binary files /dev/null and b/.cache/clangd/index/log.h.E0E90EDA1BF56D22.idx differ diff --git a/.cache/clangd/index/lshrdi3.c.F40A6E4F6735AE96.idx b/.cache/clangd/index/lshrdi3.c.F40A6E4F6735AE96.idx new file mode 100755 index 0000000..3179910 Binary files /dev/null and b/.cache/clangd/index/lshrdi3.c.F40A6E4F6735AE96.idx differ diff --git a/.cache/clangd/index/lshrti3.c.69AEAB488A42C507.idx b/.cache/clangd/index/lshrti3.c.69AEAB488A42C507.idx new file mode 100755 index 0000000..5dc9273 Binary files /dev/null and b/.cache/clangd/index/lshrti3.c.69AEAB488A42C507.idx differ diff --git a/.cache/clangd/index/main.c.24DB0DF123881CD6.idx b/.cache/clangd/index/main.c.24DB0DF123881CD6.idx new file mode 100644 index 0000000..e32054a Binary files /dev/null and b/.cache/clangd/index/main.c.24DB0DF123881CD6.idx differ diff --git a/.cache/clangd/index/moddi3.c.0937A263701885EE.idx b/.cache/clangd/index/moddi3.c.0937A263701885EE.idx new file mode 100755 index 0000000..65a7215 Binary files /dev/null and b/.cache/clangd/index/moddi3.c.0937A263701885EE.idx differ diff --git a/.cache/clangd/index/modsi3.c.24B72026862E98CE.idx b/.cache/clangd/index/modsi3.c.24B72026862E98CE.idx new file mode 100755 index 0000000..fc7193c Binary files /dev/null and b/.cache/clangd/index/modsi3.c.24B72026862E98CE.idx differ diff --git a/.cache/clangd/index/modti3.c.D1725B244F432BB4.idx b/.cache/clangd/index/modti3.c.D1725B244F432BB4.idx new file mode 100755 index 0000000..02ea08f Binary files /dev/null and b/.cache/clangd/index/modti3.c.D1725B244F432BB4.idx differ diff --git a/.cache/clangd/index/muldc3.c.8D2EEABC115A02E7.idx b/.cache/clangd/index/muldc3.c.8D2EEABC115A02E7.idx new file mode 100755 index 0000000..022c6af Binary files /dev/null and b/.cache/clangd/index/muldc3.c.8D2EEABC115A02E7.idx differ diff --git a/.cache/clangd/index/muldf3.c.A521637959212EA2.idx b/.cache/clangd/index/muldf3.c.A521637959212EA2.idx new file mode 100755 index 0000000..867020f Binary files /dev/null and b/.cache/clangd/index/muldf3.c.A521637959212EA2.idx differ diff --git a/.cache/clangd/index/muldi3.c.6FFE6349D685208F.idx b/.cache/clangd/index/muldi3.c.6FFE6349D685208F.idx new file mode 100755 index 0000000..e3ef5dd Binary files /dev/null and b/.cache/clangd/index/muldi3.c.6FFE6349D685208F.idx differ diff --git a/.cache/clangd/index/mulodi4.c.7CFF50D1BA01B277.idx b/.cache/clangd/index/mulodi4.c.7CFF50D1BA01B277.idx new file mode 100755 index 0000000..4b6db89 Binary files /dev/null and b/.cache/clangd/index/mulodi4.c.7CFF50D1BA01B277.idx differ diff --git a/.cache/clangd/index/mulosi4.c.2708019F9F2F0D0C.idx b/.cache/clangd/index/mulosi4.c.2708019F9F2F0D0C.idx new file mode 100755 index 0000000..58b622f Binary files /dev/null and b/.cache/clangd/index/mulosi4.c.2708019F9F2F0D0C.idx differ diff --git a/.cache/clangd/index/muloti4.c.DC929331B0044080.idx b/.cache/clangd/index/muloti4.c.DC929331B0044080.idx new file mode 100755 index 0000000..243cffe Binary files /dev/null and b/.cache/clangd/index/muloti4.c.DC929331B0044080.idx differ diff --git a/.cache/clangd/index/mulsc3.c.4410EACF80EF8370.idx b/.cache/clangd/index/mulsc3.c.4410EACF80EF8370.idx new file mode 100755 index 0000000..1134d13 Binary files /dev/null and b/.cache/clangd/index/mulsc3.c.4410EACF80EF8370.idx differ diff --git a/.cache/clangd/index/mulsf3.c.D8A52DEB227F4762.idx b/.cache/clangd/index/mulsf3.c.D8A52DEB227F4762.idx new file mode 100755 index 0000000..12c54c0 Binary files /dev/null and b/.cache/clangd/index/mulsf3.c.D8A52DEB227F4762.idx differ diff --git a/.cache/clangd/index/multc3.c.4BB74172095852D7.idx b/.cache/clangd/index/multc3.c.4BB74172095852D7.idx new file mode 100755 index 0000000..903dd74 Binary files /dev/null and b/.cache/clangd/index/multc3.c.4BB74172095852D7.idx differ diff --git a/.cache/clangd/index/multf3.c.CB329698B6759894.idx b/.cache/clangd/index/multf3.c.CB329698B6759894.idx new file mode 100755 index 0000000..2421211 Binary files /dev/null and b/.cache/clangd/index/multf3.c.CB329698B6759894.idx differ diff --git a/.cache/clangd/index/multi3.c.B4D485A74D27D73E.idx b/.cache/clangd/index/multi3.c.B4D485A74D27D73E.idx new file mode 100755 index 0000000..00254f7 Binary files /dev/null and b/.cache/clangd/index/multi3.c.B4D485A74D27D73E.idx differ diff --git a/.cache/clangd/index/mulvdi3.c.89FC644540984A34.idx b/.cache/clangd/index/mulvdi3.c.89FC644540984A34.idx new file mode 100755 index 0000000..3e02651 Binary files /dev/null and b/.cache/clangd/index/mulvdi3.c.89FC644540984A34.idx differ diff --git a/.cache/clangd/index/mulvsi3.c.25B42E22DE493BE9.idx b/.cache/clangd/index/mulvsi3.c.25B42E22DE493BE9.idx new file mode 100755 index 0000000..6c0eaf0 Binary files /dev/null and b/.cache/clangd/index/mulvsi3.c.25B42E22DE493BE9.idx differ diff --git a/.cache/clangd/index/mulvti3.c.BC97F078FB8E2AB9.idx b/.cache/clangd/index/mulvti3.c.BC97F078FB8E2AB9.idx new file mode 100755 index 0000000..b796d21 Binary files /dev/null and b/.cache/clangd/index/mulvti3.c.BC97F078FB8E2AB9.idx differ diff --git a/.cache/clangd/index/mulxc3.c.C38AE5C45E3B1390.idx b/.cache/clangd/index/mulxc3.c.C38AE5C45E3B1390.idx new file mode 100755 index 0000000..11a7ff2 Binary files /dev/null and b/.cache/clangd/index/mulxc3.c.C38AE5C45E3B1390.idx differ diff --git a/.cache/clangd/index/negdf2.c.69F8A3ED6F115D2D.idx b/.cache/clangd/index/negdf2.c.69F8A3ED6F115D2D.idx new file mode 100755 index 0000000..322ac36 Binary files /dev/null and b/.cache/clangd/index/negdf2.c.69F8A3ED6F115D2D.idx differ diff --git a/.cache/clangd/index/negdi2.c.BB3C09D999057BB9.idx b/.cache/clangd/index/negdi2.c.BB3C09D999057BB9.idx new file mode 100755 index 0000000..9310530 Binary files /dev/null and b/.cache/clangd/index/negdi2.c.BB3C09D999057BB9.idx differ diff --git a/.cache/clangd/index/negsf2.c.46A5F3CB8F7D8F7B.idx b/.cache/clangd/index/negsf2.c.46A5F3CB8F7D8F7B.idx new file mode 100755 index 0000000..9f37883 Binary files /dev/null and b/.cache/clangd/index/negsf2.c.46A5F3CB8F7D8F7B.idx differ diff --git a/.cache/clangd/index/negti2.c.2F8F06FD359C92A0.idx b/.cache/clangd/index/negti2.c.2F8F06FD359C92A0.idx new file mode 100755 index 0000000..dac22fc Binary files /dev/null and b/.cache/clangd/index/negti2.c.2F8F06FD359C92A0.idx differ diff --git a/.cache/clangd/index/negvdi2.c.A0002A18E7E2AEAD.idx b/.cache/clangd/index/negvdi2.c.A0002A18E7E2AEAD.idx new file mode 100755 index 0000000..36a8e0b Binary files /dev/null and b/.cache/clangd/index/negvdi2.c.A0002A18E7E2AEAD.idx differ diff --git a/.cache/clangd/index/negvsi2.c.7C1011DBC19242A9.idx b/.cache/clangd/index/negvsi2.c.7C1011DBC19242A9.idx new file mode 100755 index 0000000..f0e0804 Binary files /dev/null and b/.cache/clangd/index/negvsi2.c.7C1011DBC19242A9.idx differ diff --git a/.cache/clangd/index/negvti2.c.CCA4924AE800790B.idx b/.cache/clangd/index/negvti2.c.CCA4924AE800790B.idx new file mode 100755 index 0000000..b022321 Binary files /dev/null and b/.cache/clangd/index/negvti2.c.CCA4924AE800790B.idx differ diff --git a/.cache/clangd/index/paritydi2.c.76303EDF321B5405.idx b/.cache/clangd/index/paritydi2.c.76303EDF321B5405.idx new file mode 100755 index 0000000..fda9637 Binary files /dev/null and b/.cache/clangd/index/paritydi2.c.76303EDF321B5405.idx differ diff --git a/.cache/clangd/index/paritysi2.c.73B893623308E5CD.idx b/.cache/clangd/index/paritysi2.c.73B893623308E5CD.idx new file mode 100755 index 0000000..96ae2f4 Binary files /dev/null and b/.cache/clangd/index/paritysi2.c.73B893623308E5CD.idx differ diff --git a/.cache/clangd/index/parityti2.c.6C41F097F0FB3C41.idx b/.cache/clangd/index/parityti2.c.6C41F097F0FB3C41.idx new file mode 100755 index 0000000..81f3975 Binary files /dev/null and b/.cache/clangd/index/parityti2.c.6C41F097F0FB3C41.idx differ diff --git a/.cache/clangd/index/pit.h.FCBDD7EB679035C0.idx b/.cache/clangd/index/pit.h.FCBDD7EB679035C0.idx new file mode 100755 index 0000000..d9935fa Binary files /dev/null and b/.cache/clangd/index/pit.h.FCBDD7EB679035C0.idx differ diff --git a/.cache/clangd/index/pmm.h.B0CABFB950313E4E.idx b/.cache/clangd/index/pmm.h.B0CABFB950313E4E.idx new file mode 100755 index 0000000..0988c68 Binary files /dev/null and b/.cache/clangd/index/pmm.h.B0CABFB950313E4E.idx differ diff --git a/.cache/clangd/index/popcountdi2.c.8F0CCB351D70021D.idx b/.cache/clangd/index/popcountdi2.c.8F0CCB351D70021D.idx new file mode 100755 index 0000000..37d892e Binary files /dev/null and b/.cache/clangd/index/popcountdi2.c.8F0CCB351D70021D.idx differ diff --git a/.cache/clangd/index/popcountsi2.c.E33B79144AFF0E5F.idx b/.cache/clangd/index/popcountsi2.c.E33B79144AFF0E5F.idx new file mode 100755 index 0000000..e081068 Binary files /dev/null and b/.cache/clangd/index/popcountsi2.c.E33B79144AFF0E5F.idx differ diff --git a/.cache/clangd/index/popcountti2.c.0F09C67FEBF85406.idx b/.cache/clangd/index/popcountti2.c.0F09C67FEBF85406.idx new file mode 100755 index 0000000..6af6ee3 Binary files /dev/null and b/.cache/clangd/index/popcountti2.c.0F09C67FEBF85406.idx differ diff --git a/.cache/clangd/index/powidf2.c.93DBC174A55353AA.idx b/.cache/clangd/index/powidf2.c.93DBC174A55353AA.idx new file mode 100755 index 0000000..5950121 Binary files /dev/null and b/.cache/clangd/index/powidf2.c.93DBC174A55353AA.idx differ diff --git a/.cache/clangd/index/powisf2.c.E7998BCBE33C5284.idx b/.cache/clangd/index/powisf2.c.E7998BCBE33C5284.idx new file mode 100755 index 0000000..58a1f8d Binary files /dev/null and b/.cache/clangd/index/powisf2.c.E7998BCBE33C5284.idx differ diff --git a/.cache/clangd/index/powitf2.c.BDF9DBAB7347A575.idx b/.cache/clangd/index/powitf2.c.BDF9DBAB7347A575.idx new file mode 100755 index 0000000..805914e Binary files /dev/null and b/.cache/clangd/index/powitf2.c.BDF9DBAB7347A575.idx differ diff --git a/.cache/clangd/index/powixf2.c.F04F47FDE1D34D1F.idx b/.cache/clangd/index/powixf2.c.F04F47FDE1D34D1F.idx new file mode 100755 index 0000000..ed986ae Binary files /dev/null and b/.cache/clangd/index/powixf2.c.F04F47FDE1D34D1F.idx differ diff --git a/.cache/clangd/index/printf.h.B451F1322E27C263.idx b/.cache/clangd/index/printf.h.B451F1322E27C263.idx new file mode 100755 index 0000000..62124e4 Binary files /dev/null and b/.cache/clangd/index/printf.h.B451F1322E27C263.idx differ diff --git a/.cache/clangd/index/rt.h.4DE1465D2E715A49.idx b/.cache/clangd/index/rt.h.4DE1465D2E715A49.idx new file mode 100755 index 0000000..cdc148f Binary files /dev/null and b/.cache/clangd/index/rt.h.4DE1465D2E715A49.idx differ diff --git a/.cache/clangd/index/rtc.h.EEC94DA1B55B20C6.idx b/.cache/clangd/index/rtc.h.EEC94DA1B55B20C6.idx new file mode 100755 index 0000000..79a7c66 Binary files /dev/null and b/.cache/clangd/index/rtc.h.EEC94DA1B55B20C6.idx differ diff --git a/.cache/clangd/index/sched.h.E76F87C7BB1A08D8.idx b/.cache/clangd/index/sched.h.E76F87C7BB1A08D8.idx new file mode 100644 index 0000000..3a4216f Binary files /dev/null and b/.cache/clangd/index/sched.h.E76F87C7BB1A08D8.idx differ diff --git a/.cache/clangd/index/sse.h.508BF40E84B183FB.idx b/.cache/clangd/index/sse.h.508BF40E84B183FB.idx new file mode 100755 index 0000000..0444dd8 Binary files /dev/null and b/.cache/clangd/index/sse.h.508BF40E84B183FB.idx differ diff --git a/.cache/clangd/index/stdarg.h.A9A08A3B143D24C3.idx b/.cache/clangd/index/stdarg.h.A9A08A3B143D24C3.idx new file mode 100755 index 0000000..bea4009 Binary files /dev/null and b/.cache/clangd/index/stdarg.h.A9A08A3B143D24C3.idx differ diff --git a/.cache/clangd/index/stdbool.h.0693D9FEB5499621.idx b/.cache/clangd/index/stdbool.h.0693D9FEB5499621.idx new file mode 100755 index 0000000..4b52338 Binary files /dev/null and b/.cache/clangd/index/stdbool.h.0693D9FEB5499621.idx differ diff --git a/.cache/clangd/index/stddef.h.DD16386422A95BDA.idx b/.cache/clangd/index/stddef.h.DD16386422A95BDA.idx new file mode 100755 index 0000000..2e55d41 Binary files /dev/null and b/.cache/clangd/index/stddef.h.DD16386422A95BDA.idx differ diff --git a/.cache/clangd/index/stdint.h.465D5E9EFF387506.idx b/.cache/clangd/index/stdint.h.465D5E9EFF387506.idx new file mode 100755 index 0000000..dff84ee Binary files /dev/null and b/.cache/clangd/index/stdint.h.465D5E9EFF387506.idx differ diff --git a/.cache/clangd/index/subdf3.c.7B4DE2500F85491F.idx b/.cache/clangd/index/subdf3.c.7B4DE2500F85491F.idx new file mode 100755 index 0000000..ba1c54d Binary files /dev/null and b/.cache/clangd/index/subdf3.c.7B4DE2500F85491F.idx differ diff --git a/.cache/clangd/index/subsf3.c.B8379285A8FB1003.idx b/.cache/clangd/index/subsf3.c.B8379285A8FB1003.idx new file mode 100755 index 0000000..f673cb4 Binary files /dev/null and b/.cache/clangd/index/subsf3.c.B8379285A8FB1003.idx differ diff --git a/.cache/clangd/index/subtf3.c.2A1CE141BC778302.idx b/.cache/clangd/index/subtf3.c.2A1CE141BC778302.idx new file mode 100755 index 0000000..5ca67fc Binary files /dev/null and b/.cache/clangd/index/subtf3.c.2A1CE141BC778302.idx differ diff --git a/.cache/clangd/index/subvdi3.c.36C79223A475F797.idx b/.cache/clangd/index/subvdi3.c.36C79223A475F797.idx new file mode 100755 index 0000000..2b215b5 Binary files /dev/null and b/.cache/clangd/index/subvdi3.c.36C79223A475F797.idx differ diff --git a/.cache/clangd/index/subvsi3.c.A5D87882A951E5E7.idx b/.cache/clangd/index/subvsi3.c.A5D87882A951E5E7.idx new file mode 100755 index 0000000..9a26ccd Binary files /dev/null and b/.cache/clangd/index/subvsi3.c.A5D87882A951E5E7.idx differ diff --git a/.cache/clangd/index/subvti3.c.829111C90A78F5E3.idx b/.cache/clangd/index/subvti3.c.829111C90A78F5E3.idx new file mode 100755 index 0000000..1daa317 Binary files /dev/null and b/.cache/clangd/index/subvti3.c.829111C90A78F5E3.idx differ diff --git a/.cache/clangd/index/truncdfbf2.c.5C4053C67A050699.idx b/.cache/clangd/index/truncdfbf2.c.5C4053C67A050699.idx new file mode 100755 index 0000000..637455a Binary files /dev/null and b/.cache/clangd/index/truncdfbf2.c.5C4053C67A050699.idx differ diff --git a/.cache/clangd/index/truncdfhf2.c.3A5024083614A0CD.idx b/.cache/clangd/index/truncdfhf2.c.3A5024083614A0CD.idx new file mode 100755 index 0000000..1958871 Binary files /dev/null and b/.cache/clangd/index/truncdfhf2.c.3A5024083614A0CD.idx differ diff --git a/.cache/clangd/index/truncdfsf2.c.A03358D45B4ED38F.idx b/.cache/clangd/index/truncdfsf2.c.A03358D45B4ED38F.idx new file mode 100755 index 0000000..e343900 Binary files /dev/null and b/.cache/clangd/index/truncdfsf2.c.A03358D45B4ED38F.idx differ diff --git a/.cache/clangd/index/truncsfbf2.c.62ADA672DACBA367.idx b/.cache/clangd/index/truncsfbf2.c.62ADA672DACBA367.idx new file mode 100755 index 0000000..6dae5ab Binary files /dev/null and b/.cache/clangd/index/truncsfbf2.c.62ADA672DACBA367.idx differ diff --git a/.cache/clangd/index/truncsfhf2.c.3FFEF4DC19E99F2E.idx b/.cache/clangd/index/truncsfhf2.c.3FFEF4DC19E99F2E.idx new file mode 100755 index 0000000..7f85598 Binary files /dev/null and b/.cache/clangd/index/truncsfhf2.c.3FFEF4DC19E99F2E.idx differ diff --git a/.cache/clangd/index/trunctfdf2.c.FD9D1EAC94E4DA09.idx b/.cache/clangd/index/trunctfdf2.c.FD9D1EAC94E4DA09.idx new file mode 100755 index 0000000..29fe9ad Binary files /dev/null and b/.cache/clangd/index/trunctfdf2.c.FD9D1EAC94E4DA09.idx differ diff --git a/.cache/clangd/index/trunctfhf2.c.D2EAB4EF390B11D1.idx b/.cache/clangd/index/trunctfhf2.c.D2EAB4EF390B11D1.idx new file mode 100755 index 0000000..92ca0d2 Binary files /dev/null and b/.cache/clangd/index/trunctfhf2.c.D2EAB4EF390B11D1.idx differ diff --git a/.cache/clangd/index/trunctfsf2.c.B377EBF78748EF30.idx b/.cache/clangd/index/trunctfsf2.c.B377EBF78748EF30.idx new file mode 100755 index 0000000..54c19a3 Binary files /dev/null and b/.cache/clangd/index/trunctfsf2.c.B377EBF78748EF30.idx differ diff --git a/.cache/clangd/index/trunctfxf2.c.19981BF10FD2F99E.idx b/.cache/clangd/index/trunctfxf2.c.19981BF10FD2F99E.idx new file mode 100755 index 0000000..a1321e3 Binary files /dev/null and b/.cache/clangd/index/trunctfxf2.c.19981BF10FD2F99E.idx differ diff --git a/.cache/clangd/index/truncxfbf2.c.F9E9DA66F162327F.idx b/.cache/clangd/index/truncxfbf2.c.F9E9DA66F162327F.idx new file mode 100755 index 0000000..8ff4d23 Binary files /dev/null and b/.cache/clangd/index/truncxfbf2.c.F9E9DA66F162327F.idx differ diff --git a/.cache/clangd/index/ucmpdi2.c.084AEC36084D5BB3.idx b/.cache/clangd/index/ucmpdi2.c.084AEC36084D5BB3.idx new file mode 100755 index 0000000..d7f71eb Binary files /dev/null and b/.cache/clangd/index/ucmpdi2.c.084AEC36084D5BB3.idx differ diff --git a/.cache/clangd/index/ucmpti2.c.8E1052AFD84404FD.idx b/.cache/clangd/index/ucmpti2.c.8E1052AFD84404FD.idx new file mode 100755 index 0000000..a2450dc Binary files /dev/null and b/.cache/clangd/index/ucmpti2.c.8E1052AFD84404FD.idx differ diff --git a/.cache/clangd/index/udivdi3.c.561304CA1C1BE0E9.idx b/.cache/clangd/index/udivdi3.c.561304CA1C1BE0E9.idx new file mode 100755 index 0000000..acb64b5 Binary files /dev/null and b/.cache/clangd/index/udivdi3.c.561304CA1C1BE0E9.idx differ diff --git a/.cache/clangd/index/udivmoddi4.c.70F2B64E31B6BC69.idx b/.cache/clangd/index/udivmoddi4.c.70F2B64E31B6BC69.idx new file mode 100755 index 0000000..86c8a2a Binary files /dev/null and b/.cache/clangd/index/udivmoddi4.c.70F2B64E31B6BC69.idx differ diff --git a/.cache/clangd/index/udivmodsi4.c.8138533E2886502D.idx b/.cache/clangd/index/udivmodsi4.c.8138533E2886502D.idx new file mode 100755 index 0000000..3fcd9d9 Binary files /dev/null and b/.cache/clangd/index/udivmodsi4.c.8138533E2886502D.idx differ diff --git a/.cache/clangd/index/udivmodti4.c.46DA76158F034612.idx b/.cache/clangd/index/udivmodti4.c.46DA76158F034612.idx new file mode 100755 index 0000000..42415cd Binary files /dev/null and b/.cache/clangd/index/udivmodti4.c.46DA76158F034612.idx differ diff --git a/.cache/clangd/index/udivsi3.c.B3F1B82AE31AA297.idx b/.cache/clangd/index/udivsi3.c.B3F1B82AE31AA297.idx new file mode 100755 index 0000000..75cd13f Binary files /dev/null and b/.cache/clangd/index/udivsi3.c.B3F1B82AE31AA297.idx differ diff --git a/.cache/clangd/index/udivti3.c.E62428D445E7E7BF.idx b/.cache/clangd/index/udivti3.c.E62428D445E7E7BF.idx new file mode 100755 index 0000000..ac93734 Binary files /dev/null and b/.cache/clangd/index/udivti3.c.E62428D445E7E7BF.idx differ diff --git a/.cache/clangd/index/umoddi3.c.08FC9E378DFD72A1.idx b/.cache/clangd/index/umoddi3.c.08FC9E378DFD72A1.idx new file mode 100755 index 0000000..d8d9ec2 Binary files /dev/null and b/.cache/clangd/index/umoddi3.c.08FC9E378DFD72A1.idx differ diff --git a/.cache/clangd/index/umodsi3.c.7A9476DD12568553.idx b/.cache/clangd/index/umodsi3.c.7A9476DD12568553.idx new file mode 100755 index 0000000..bee5806 Binary files /dev/null and b/.cache/clangd/index/umodsi3.c.7A9476DD12568553.idx differ diff --git a/.cache/clangd/index/umodti3.c.DB9DB5C81AF2F756.idx b/.cache/clangd/index/umodti3.c.DB9DB5C81AF2F756.idx new file mode 100755 index 0000000..d9f1cbf Binary files /dev/null and b/.cache/clangd/index/umodti3.c.DB9DB5C81AF2F756.idx differ diff --git a/.cache/clangd/index/vmm.h.3958D0C383864F44.idx b/.cache/clangd/index/vmm.h.3958D0C383864F44.idx new file mode 100755 index 0000000..f1f0ddf Binary files /dev/null and b/.cache/clangd/index/vmm.h.3958D0C383864F44.idx differ diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..e6967fd --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/kernel-deps +/limine +/ovmf +*.iso +*.hdd diff --git a/GNUmakefile b/GNUmakefile new file mode 100755 index 0000000..554455d --- /dev/null +++ b/GNUmakefile @@ -0,0 +1,258 @@ +# Nuke built-in rules and variables. +MAKEFLAGS += -rR +.SUFFIXES: + +# Target architecture to build for. Default to x86_64. +ARCH := x86_64 + +# Default user QEMU flags. These are appended to the QEMU command calls. +QEMUFLAGS := -m 2G -debugcon stdio -no-reboot -no-shutdown + +override IMAGE_NAME := sild-live-$(ARCH) + +# Toolchain for building the 'limine' executable for the host. +HOST_CC := cc +HOST_CFLAGS := -g -O2 -pipe +HOST_CPPFLAGS := +HOST_LDFLAGS := +HOST_LIBS := + +.PHONY: all +all: $(IMAGE_NAME).iso + +.PHONY: all-hdd +all-hdd: $(IMAGE_NAME).hdd + +.PHONY: run +run: run-$(ARCH) + +.PHONY: run-hdd +run-hdd: run-hdd-$(ARCH) + +.PHONY: ints +ints: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).iso + qemu-system-$(ARCH) \ + -M q35 \ + -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(ARCH).fd,readonly=on \ + -cdrom $(IMAGE_NAME).iso \ + -d int \ + $(QEMUFLAGS) + +.PHONY: run-x86_64 +run-x86_64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).iso + qemu-system-$(ARCH) \ + -M q35 \ + -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(ARCH).fd,readonly=on \ + -cdrom $(IMAGE_NAME).iso \ + $(QEMUFLAGS) + +.PHONY: run-hdd-x86_64 +run-hdd-x86_64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).hdd + qemu-system-$(ARCH) \ + -M q35 \ + -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(ARCH).fd,readonly=on \ + -hda $(IMAGE_NAME).hdd \ + $(QEMUFLAGS) + +.PHONY: run-aarch64 +run-aarch64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).iso + qemu-system-$(ARCH) \ + -M virt \ + -cpu cortex-a72 \ + -device ramfb \ + -device qemu-xhci \ + -device usb-kbd \ + -device usb-mouse \ + -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(ARCH).fd,readonly=on \ + -cdrom $(IMAGE_NAME).iso \ + $(QEMUFLAGS) + +.PHONY: run-hdd-aarch64 +run-hdd-aarch64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).hdd + qemu-system-$(ARCH) \ + -M virt \ + -cpu cortex-a72 \ + -device ramfb \ + -device qemu-xhci \ + -device usb-kbd \ + -device usb-mouse \ + -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(ARCH).fd,readonly=on \ + -hda $(IMAGE_NAME).hdd \ + $(QEMUFLAGS) + +.PHONY: run-riscv64 +run-riscv64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).iso + qemu-system-$(ARCH) \ + -M virt \ + -cpu rv64 \ + -device ramfb \ + -device qemu-xhci \ + -device usb-kbd \ + -device usb-mouse \ + -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(ARCH).fd,readonly=on \ + -cdrom $(IMAGE_NAME).iso \ + $(QEMUFLAGS) + +.PHONY: run-hdd-riscv64 +run-hdd-riscv64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).hdd + qemu-system-$(ARCH) \ + -M virt \ + -cpu rv64 \ + -device ramfb \ + -device qemu-xhci \ + -device usb-kbd \ + -device usb-mouse \ + -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(ARCH).fd,readonly=on \ + -hda $(IMAGE_NAME).hdd \ + $(QEMUFLAGS) + +.PHONY: run-loongarch64 +run-loongarch64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).iso + qemu-system-$(ARCH) \ + -M virt \ + -cpu la464 \ + -device ramfb \ + -device qemu-xhci \ + -device usb-kbd \ + -device usb-mouse \ + -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(ARCH).fd,readonly=on \ + -cdrom $(IMAGE_NAME).iso \ + $(QEMUFLAGS) + +.PHONY: run-hdd-loongarch64 +run-hdd-loongarch64: ovmf/ovmf-code-$(ARCH).fd $(IMAGE_NAME).hdd + qemu-system-$(ARCH) \ + -M virt \ + -cpu la464 \ + -device ramfb \ + -device qemu-xhci \ + -device usb-kbd \ + -device usb-mouse \ + -drive if=pflash,unit=0,format=raw,file=ovmf/ovmf-code-$(ARCH).fd,readonly=on \ + -hda $(IMAGE_NAME).hdd \ + $(QEMUFLAGS) + + +.PHONY: run-bios +run-bios: $(IMAGE_NAME).iso + qemu-system-$(ARCH) \ + -M q35 \ + -cdrom $(IMAGE_NAME).iso \ + -boot d \ + $(QEMUFLAGS) + +.PHONY: run-hdd-bios +run-hdd-bios: $(IMAGE_NAME).hdd + qemu-system-$(ARCH) \ + -M q35 \ + -hda $(IMAGE_NAME).hdd \ + $(QEMUFLAGS) + +ovmf/ovmf-code-$(ARCH).fd: + mkdir -p ovmf + curl -Lo $@ https://github.com/osdev0/edk2-ovmf-nightly/releases/latest/download/ovmf-code-$(ARCH).fd + case "$(ARCH)" in \ + aarch64) dd if=/dev/zero of=$@ bs=1 count=0 seek=67108864 2>/dev/null;; \ + riscv64) dd if=/dev/zero of=$@ bs=1 count=0 seek=33554432 2>/dev/null;; \ + esac + +limine/limine: + rm -rf limine + git clone https://github.com/limine-bootloader/limine.git --branch=v9.x-binary --depth=1 + $(MAKE) -C limine \ + CC="$(HOST_CC)" \ + CFLAGS="$(HOST_CFLAGS)" \ + CPPFLAGS="$(HOST_CPPFLAGS)" \ + LDFLAGS="$(HOST_LDFLAGS)" \ + LIBS="$(HOST_LIBS)" + +kernel-deps: + ./kernel/get-deps + touch kernel-deps + +.PHONY: kernel +kernel: kernel-deps + $(MAKE) -C kernel + +$(IMAGE_NAME).iso: limine/limine kernel + rm -rf iso_root + mkdir -p iso_root/boot + cp -v kernel/bin-$(ARCH)/kernel iso_root/boot/ + mkdir -p iso_root/boot/limine + cp -v limine.conf iso_root/boot/limine/ + mkdir -p iso_root/EFI/BOOT +ifeq ($(ARCH),x86_64) + cp -v limine/limine-bios.sys limine/limine-bios-cd.bin limine/limine-uefi-cd.bin iso_root/boot/limine/ + cp -v limine/BOOTX64.EFI iso_root/EFI/BOOT/ + cp -v limine/BOOTIA32.EFI iso_root/EFI/BOOT/ + xorriso -as mkisofs -R -r -J -b boot/limine/limine-bios-cd.bin \ + -no-emul-boot -boot-load-size 4 -boot-info-table -hfsplus \ + -apm-block-size 2048 --efi-boot boot/limine/limine-uefi-cd.bin \ + -efi-boot-part --efi-boot-image --protective-msdos-label \ + iso_root -o $(IMAGE_NAME).iso + ./limine/limine bios-install $(IMAGE_NAME).iso +endif +ifeq ($(ARCH),aarch64) + cp -v limine/limine-uefi-cd.bin iso_root/boot/limine/ + cp -v limine/BOOTAA64.EFI iso_root/EFI/BOOT/ + xorriso -as mkisofs -R -r -J \ + -hfsplus -apm-block-size 2048 \ + --efi-boot boot/limine/limine-uefi-cd.bin \ + -efi-boot-part --efi-boot-image --protective-msdos-label \ + iso_root -o $(IMAGE_NAME).iso +endif +ifeq ($(ARCH),riscv64) + cp -v limine/limine-uefi-cd.bin iso_root/boot/limine/ + cp -v limine/BOOTRISCV64.EFI iso_root/EFI/BOOT/ + xorriso -as mkisofs -R -r -J \ + -hfsplus -apm-block-size 2048 \ + --efi-boot boot/limine/limine-uefi-cd.bin \ + -efi-boot-part --efi-boot-image --protective-msdos-label \ + iso_root -o $(IMAGE_NAME).iso +endif +ifeq ($(ARCH),loongarch64) + cp -v limine/limine-uefi-cd.bin iso_root/boot/limine/ + cp -v limine/BOOTLOONGARCH64.EFI iso_root/EFI/BOOT/ + xorriso -as mkisofs -R -r -J \ + -hfsplus -apm-block-size 2048 \ + --efi-boot boot/limine/limine-uefi-cd.bin \ + -efi-boot-part --efi-boot-image --protective-msdos-label \ + iso_root -o $(IMAGE_NAME).iso +endif + rm -rf iso_root + +$(IMAGE_NAME).hdd: limine/limine kernel + rm -f $(IMAGE_NAME).hdd + dd if=/dev/zero bs=1M count=0 seek=64 of=$(IMAGE_NAME).hdd + PATH=$$PATH:/usr/sbin:/sbin sgdisk $(IMAGE_NAME).hdd -n 1:2048 -t 1:ef00 +ifeq ($(ARCH),x86_64) + ./limine/limine bios-install $(IMAGE_NAME).hdd +endif + mformat -i $(IMAGE_NAME).hdd@@1M + mmd -i $(IMAGE_NAME).hdd@@1M ::/EFI ::/EFI/BOOT ::/boot ::/boot/limine + mcopy -i $(IMAGE_NAME).hdd@@1M kernel/bin-$(ARCH)/kernel ::/boot + mcopy -i $(IMAGE_NAME).hdd@@1M limine.conf ::/boot/limine +ifeq ($(ARCH),x86_64) + mcopy -i $(IMAGE_NAME).hdd@@1M limine/limine-bios.sys ::/boot/limine + mcopy -i $(IMAGE_NAME).hdd@@1M limine/BOOTX64.EFI ::/EFI/BOOT + mcopy -i $(IMAGE_NAME).hdd@@1M limine/BOOTIA32.EFI ::/EFI/BOOT +endif +ifeq ($(ARCH),aarch64) + mcopy -i $(IMAGE_NAME).hdd@@1M limine/BOOTAA64.EFI ::/EFI/BOOT +endif +ifeq ($(ARCH),riscv64) + mcopy -i $(IMAGE_NAME).hdd@@1M limine/BOOTRISCV64.EFI ::/EFI/BOOT +endif +ifeq ($(ARCH),loongarch64) + mcopy -i $(IMAGE_NAME).hdd@@1M limine/BOOTLOONGARCH64.EFI ::/EFI/BOOT +endif + +.PHONY: clean +clean: + $(MAKE) -C kernel clean + rm -rf iso_root $(IMAGE_NAME).iso $(IMAGE_NAME).hdd + +.PHONY: distclean +distclean: + $(MAKE) -C kernel distclean + rm -rf iso_root *.iso *.hdd kernel-deps limine ovmf diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000..295294b --- /dev/null +++ b/LICENSE @@ -0,0 +1,12 @@ +Copyright (C) 2023-2025 mintsuki and contributors. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/README.md b/README.md new file mode 100755 index 0000000..795a5f5 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# SILD (SILD isn't a Linux distro) \ No newline at end of file diff --git a/_.git/HEAD b/_.git/HEAD new file mode 100755 index 0000000..8a752b6 --- /dev/null +++ b/_.git/HEAD @@ -0,0 +1 @@ +ref: refs/heads/trunk diff --git a/_.git/config b/_.git/config new file mode 100755 index 0000000..438fd28 --- /dev/null +++ b/_.git/config @@ -0,0 +1,12 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true +[remote "origin"] + url = https://github.com/limine-bootloader/limine-c-template + fetch = +refs/heads/*:refs/remotes/origin/* +[branch "trunk"] + remote = origin + merge = refs/heads/trunk + vscode-merge-base = origin/trunk diff --git a/_.git/description b/_.git/description new file mode 100755 index 0000000..498b267 --- /dev/null +++ b/_.git/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/_.git/hooks/applypatch-msg.sample b/_.git/hooks/applypatch-msg.sample new file mode 100755 index 0000000..a5d7b84 --- /dev/null +++ b/_.git/hooks/applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/_.git/hooks/commit-msg.sample b/_.git/hooks/commit-msg.sample new file mode 100755 index 0000000..b58d118 --- /dev/null +++ b/_.git/hooks/commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/_.git/hooks/fsmonitor-watchman.sample b/_.git/hooks/fsmonitor-watchman.sample new file mode 100755 index 0000000..23e856f --- /dev/null +++ b/_.git/hooks/fsmonitor-watchman.sample @@ -0,0 +1,174 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 2) and last update token +# formatted as a string and outputs to stdout a new update token and +# all files that have been modified since the update token. Paths must +# be relative to the root of the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $last_update_token) = @ARGV; + +# Uncomment for debugging +# print STDERR "$0 $version $last_update_token\n"; + +# Check the hook interface version +if ($version ne 2) { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree = get_working_dir(); + +my $retry = 1; + +my $json_pkg; +eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; +} or do { + require JSON::PP; + $json_pkg = "JSON::PP"; +}; + +launch_watchman(); + +sub launch_watchman { + my $o = watchman_query(); + if (is_work_tree_watched($o)) { + output_result($o->{clock}, @{$o->{files}}); + } +} + +sub output_result { + my ($clockid, @files) = @_; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # binmode $fh, ":utf8"; + # print $fh "$clockid\n@files\n"; + # close $fh; + + binmode STDOUT, ":utf8"; + print $clockid; + print "\0"; + local $, = "\0"; + print @files; +} + +sub watchman_clock { + my $response = qx/watchman clock "$git_work_tree"/; + die "Failed to get clock id on '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + return $json_pkg->new->utf8->decode($response); +} + +sub watchman_query { + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $last_update_token but not from the .git folder. + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + my $last_update_line = ""; + if (substr($last_update_token, 0, 1) eq "c") { + $last_update_token = "\"$last_update_token\""; + $last_update_line = qq[\n"since": $last_update_token,]; + } + my $query = <<" END"; + ["query", "$git_work_tree", {$last_update_line + "fields": ["name"], + "expression": ["not", ["dirname", ".git"]] + }] + END + + # Uncomment for debugging the watchman query + # open (my $fh, ">", ".git/watchman-query.json"); + # print $fh $query; + # close $fh; + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; }; + + # Uncomment for debugging the watch response + # open ($fh, ">", ".git/watchman-response.json"); + # print $fh $response; + # close $fh; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + return $json_pkg->new->utf8->decode($response); +} + +sub is_work_tree_watched { + my ($output) = @_; + my $error = $output->{error}; + if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { + $retry--; + my $response = qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + $output = $json_pkg->new->utf8->decode($response); + $error = $output->{error}; + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # close $fh; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + my $o = watchman_clock(); + $error = $output->{error}; + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + output_result($o->{clock}, ("/")); + $last_update_token = $o->{clock}; + + eval { launch_watchman() }; + return 0; + } + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + return 1; +} + +sub get_working_dir { + my $working_dir; + if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $working_dir = Win32::GetCwd(); + $working_dir =~ tr/\\/\//; + } else { + require Cwd; + $working_dir = Cwd::cwd(); + } + + return $working_dir; +} diff --git a/_.git/hooks/post-update.sample b/_.git/hooks/post-update.sample new file mode 100755 index 0000000..ec17ec1 --- /dev/null +++ b/_.git/hooks/post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/_.git/hooks/pre-applypatch.sample b/_.git/hooks/pre-applypatch.sample new file mode 100755 index 0000000..4142082 --- /dev/null +++ b/_.git/hooks/pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/_.git/hooks/pre-commit.sample b/_.git/hooks/pre-commit.sample new file mode 100755 index 0000000..29ed5ee --- /dev/null +++ b/_.git/hooks/pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --type=bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff-index --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/_.git/hooks/pre-merge-commit.sample b/_.git/hooks/pre-merge-commit.sample new file mode 100755 index 0000000..399eab1 --- /dev/null +++ b/_.git/hooks/pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: diff --git a/_.git/hooks/pre-push.sample b/_.git/hooks/pre-push.sample new file mode 100755 index 0000000..4ce688d --- /dev/null +++ b/_.git/hooks/pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +zero=$(git hash-object --stdin &2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/_.git/hooks/pre-rebase.sample b/_.git/hooks/pre-rebase.sample new file mode 100755 index 0000000..6cbef5c --- /dev/null +++ b/_.git/hooks/pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/_.git/hooks/pre-receive.sample b/_.git/hooks/pre-receive.sample new file mode 100755 index 0000000..a1fd29e --- /dev/null +++ b/_.git/hooks/pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/_.git/hooks/prepare-commit-msg.sample b/_.git/hooks/prepare-commit-msg.sample new file mode 100755 index 0000000..10fa14c --- /dev/null +++ b/_.git/hooks/prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/_.git/hooks/push-to-checkout.sample b/_.git/hooks/push-to-checkout.sample new file mode 100755 index 0000000..af5a0c0 --- /dev/null +++ b/_.git/hooks/push-to-checkout.sample @@ -0,0 +1,78 @@ +#!/bin/sh + +# An example hook script to update a checked-out tree on a git push. +# +# This hook is invoked by git-receive-pack(1) when it reacts to git +# push and updates reference(s) in its repository, and when the push +# tries to update the branch that is currently checked out and the +# receive.denyCurrentBranch configuration variable is set to +# updateInstead. +# +# By default, such a push is refused if the working tree and the index +# of the remote repository has any difference from the currently +# checked out commit; when both the working tree and the index match +# the current commit, they are updated to match the newly pushed tip +# of the branch. This hook is to be used to override the default +# behaviour; however the code below reimplements the default behaviour +# as a starting point for convenient modification. +# +# The hook receives the commit with which the tip of the current +# branch is going to be updated: +commit=$1 + +# It can exit with a non-zero status to refuse the push (when it does +# so, it must not modify the index or the working tree). +die () { + echo >&2 "$*" + exit 1 +} + +# Or it can make any necessary changes to the working tree and to the +# index to bring them to the desired state when the tip of the current +# branch is updated to the new commit, and exit with a zero status. +# +# For example, the hook can simply run git read-tree -u -m HEAD "$1" +# in order to emulate git fetch that is run in the reverse direction +# with git push, as the two-tree form of git read-tree -u -m is +# essentially the same as git switch or git checkout that switches +# branches while keeping the local changes in the working tree that do +# not interfere with the difference between the branches. + +# The below is a more-or-less exact translation to shell of the C code +# for the default behaviour for git's push-to-checkout hook defined in +# the push_to_deploy() function in builtin/receive-pack.c. +# +# Note that the hook will be executed from the repository directory, +# not from the working tree, so if you want to perform operations on +# the working tree, you will have to adapt your code accordingly, e.g. +# by adding "cd .." or using relative paths. + +if ! git update-index -q --ignore-submodules --refresh +then + die "Up-to-date check failed" +fi + +if ! git diff-files --quiet --ignore-submodules -- +then + die "Working directory has unstaged changes" +fi + +# This is a rough translation of: +# +# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX +if git cat-file -e HEAD 2>/dev/null +then + head=HEAD +else + head=$(git hash-object -t tree --stdin &2 + exit 1 +} + +unset GIT_DIR GIT_WORK_TREE +cd "$worktree" && + +if grep -q "^diff --git " "$1" +then + validate_patch "$1" +else + validate_cover_letter "$1" +fi && + +if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL" +then + git config --unset-all sendemail.validateWorktree && + trap 'git worktree remove -ff "$worktree"' EXIT && + validate_series +fi diff --git a/_.git/hooks/update.sample b/_.git/hooks/update.sample new file mode 100755 index 0000000..c4d426b --- /dev/null +++ b/_.git/hooks/update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --type=bool hooks.allowunannotated) +allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch) +denycreatebranch=$(git config --type=bool hooks.denycreatebranch) +allowdeletetag=$(git config --type=bool hooks.allowdeletetag) +allowmodifytag=$(git config --type=bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero=$(git hash-object --stdin &2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/_.git/index b/_.git/index new file mode 100644 index 0000000..91602cf Binary files /dev/null and b/_.git/index differ diff --git a/_.git/info/exclude b/_.git/info/exclude new file mode 100755 index 0000000..a5196d1 --- /dev/null +++ b/_.git/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/_.git/logs/HEAD b/_.git/logs/HEAD new file mode 100755 index 0000000..a34e057 --- /dev/null +++ b/_.git/logs/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 976ef51b0ff31f7e1f8f38994e23723496b6745f raphm 1740611964 +0100 clone: from https://github.com/limine-bootloader/limine-c-template diff --git a/_.git/logs/refs/heads/trunk b/_.git/logs/refs/heads/trunk new file mode 100755 index 0000000..a34e057 --- /dev/null +++ b/_.git/logs/refs/heads/trunk @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 976ef51b0ff31f7e1f8f38994e23723496b6745f raphm 1740611964 +0100 clone: from https://github.com/limine-bootloader/limine-c-template diff --git a/_.git/logs/refs/remotes/origin/HEAD b/_.git/logs/refs/remotes/origin/HEAD new file mode 100755 index 0000000..a34e057 --- /dev/null +++ b/_.git/logs/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 976ef51b0ff31f7e1f8f38994e23723496b6745f raphm 1740611964 +0100 clone: from https://github.com/limine-bootloader/limine-c-template diff --git a/_.git/objects/pack/pack-2706704623c6f502f1188ffe246bc5ef0196c18f.idx b/_.git/objects/pack/pack-2706704623c6f502f1188ffe246bc5ef0196c18f.idx new file mode 100755 index 0000000..7fb5be0 Binary files /dev/null and b/_.git/objects/pack/pack-2706704623c6f502f1188ffe246bc5ef0196c18f.idx differ diff --git a/_.git/objects/pack/pack-2706704623c6f502f1188ffe246bc5ef0196c18f.pack b/_.git/objects/pack/pack-2706704623c6f502f1188ffe246bc5ef0196c18f.pack new file mode 100755 index 0000000..334486f Binary files /dev/null and b/_.git/objects/pack/pack-2706704623c6f502f1188ffe246bc5ef0196c18f.pack differ diff --git a/_.git/objects/pack/pack-2706704623c6f502f1188ffe246bc5ef0196c18f.rev b/_.git/objects/pack/pack-2706704623c6f502f1188ffe246bc5ef0196c18f.rev new file mode 100755 index 0000000..bac36a8 Binary files /dev/null and b/_.git/objects/pack/pack-2706704623c6f502f1188ffe246bc5ef0196c18f.rev differ diff --git a/_.git/packed-refs b/_.git/packed-refs new file mode 100755 index 0000000..6126578 --- /dev/null +++ b/_.git/packed-refs @@ -0,0 +1,2 @@ +# pack-refs with: peeled fully-peeled sorted +976ef51b0ff31f7e1f8f38994e23723496b6745f refs/remotes/origin/trunk diff --git a/_.git/refs/heads/trunk b/_.git/refs/heads/trunk new file mode 100755 index 0000000..e95fa4d --- /dev/null +++ b/_.git/refs/heads/trunk @@ -0,0 +1 @@ +976ef51b0ff31f7e1f8f38994e23723496b6745f diff --git a/_.git/refs/remotes/origin/HEAD b/_.git/refs/remotes/origin/HEAD new file mode 100755 index 0000000..ac41ed5 --- /dev/null +++ b/_.git/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +ref: refs/remotes/origin/trunk diff --git a/compile_commands.json b/compile_commands.json new file mode 100755 index 0000000..f556a44 --- /dev/null +++ b/compile_commands.json @@ -0,0 +1,40 @@ +[ + { + "arguments": [ + "/usr/bin/cc", + "-g", + "-O2", + "-pipe", + "-Wall", + "-Wextra", + "-std=gnu11", + "-nostdinc", + "-ffreestanding", + "-fno-stack-protector", + "-fno-stack-check", + "-fno-PIC", + "-ffunction-sections", + "-fdata-sections", + "-m64", + "-march=x86-64", + "-mno-80387", + "-mno-mmx", + "-mno-sse", + "-mno-sse2", + "-mno-red-zone", + "-mcmodel=kernel", + "-I", + "src", + "-isystem", + "freestnd-c-hdrs", + "-DLIMINE_API_REVISION=3", + "-c", + "-o", + "obj-x86_64/main.c.o", + "src/main.c" + ], + "directory": "/home/raphm/Projets/sild/kernel", + "file": "/home/raphm/Projets/sild/kernel/src/main.c", + "output": "/home/raphm/Projets/sild/kernel/obj-x86_64/main.c.o" + } +] diff --git a/ints b/ints new file mode 100644 index 0000000..e69de29 diff --git a/kernel/.gitignore b/kernel/.gitignore new file mode 100755 index 0000000..4eeb3d0 --- /dev/null +++ b/kernel/.gitignore @@ -0,0 +1,5 @@ +/freestnd-c-hdrs +/cc-runtime* +/src/limine.h +/bin-* +/obj-* diff --git a/kernel/GNUmakefile b/kernel/GNUmakefile new file mode 100755 index 0000000..8df9eac --- /dev/null +++ b/kernel/GNUmakefile @@ -0,0 +1,220 @@ +# Nuke built-in rules and variables. +MAKEFLAGS += -rR +.SUFFIXES: + +# This is the name that our final executable will have. +# Change as needed. +override OUTPUT := kernel + +# Target architecture to build for. Default to x86_64. +ARCH := x86_64 + +# Install prefix; /usr/local is a good, standard default pick. +PREFIX := /usr/local + +# Check if the architecture is supported. +ifeq ($(filter $(ARCH),aarch64 loongarch64 riscv64 x86_64),) + $(error Architecture $(ARCH) not supported) +endif + +# User controllable C compiler command. +CC := cc + +# User controllable archiver command. +AR := ar + +# User controllable C flags. +CFLAGS := -g -O2 -pipe + +# User controllable C preprocessor flags. We set none by default. +CPPFLAGS := + +ifeq ($(ARCH),x86_64) + # User controllable nasm flags. + NASMFLAGS := -F dwarf -g +endif + +# User controllable linker flags. We set none by default. +LDFLAGS := + +# Ensure the dependencies have been obtained. +ifneq ($(shell ( test '$(MAKECMDGOALS)' = clean || test '$(MAKECMDGOALS)' = distclean ); echo $$?),0) + ifeq ($(shell ( ! test -d freestnd-c-hdrs || ! test -d cc-runtime || ! test -f src/limine.h ); echo $$?),0) + $(error Please run the ./get-deps script first) + endif +endif + +# Check if CC is Clang. +override CC_IS_CLANG := $(shell ! $(CC) --version 2>/dev/null | grep 'clang' >/dev/null 2>&1; echo $$?) + +# Internal C flags that should not be changed by the user. +override CFLAGS += \ + -Wall \ + -Wextra \ + -std=gnu11 \ + -nostdinc \ + -ffreestanding \ + -fno-stack-protector \ + -fno-stack-check \ + -fno-PIC \ + -ffunction-sections \ + -fdata-sections + +# Internal C preprocessor flags that should not be changed by the user. +override CPPFLAGS := \ + -I src \ + -isystem freestnd-c-hdrs \ + $(CPPFLAGS) \ + -DLIMINE_API_REVISION=3 \ + -MMD \ + -MP + +ifeq ($(ARCH),x86_64) + # Internal nasm flags that should not be changed by the user. + override NASMFLAGS += \ + -Wall +endif + +# Architecture specific internal flags. +ifeq ($(ARCH),x86_64) + ifeq ($(CC_IS_CLANG),1) + override CC += \ + -target x86_64-unknown-none + endif + override CFLAGS += \ + -m64 \ + -march=x86-64 \ + -mno-80387 \ + -mno-mmx \ + -mno-sse \ + -mno-sse2 \ + -mno-red-zone \ + -mcmodel=kernel + override LDFLAGS += \ + -Wl,-m,elf_x86_64 + override NASMFLAGS += \ + -f elf64 +endif +ifeq ($(ARCH),aarch64) + ifeq ($(CC_IS_CLANG),1) + override CC += \ + -target aarch64-unknown-none + endif + override CFLAGS += \ + -mgeneral-regs-only + override LDFLAGS += \ + -Wl,-m,aarch64elf +endif +ifeq ($(ARCH),riscv64) + ifeq ($(CC_IS_CLANG),1) + override CC += \ + -target riscv64-unknown-none + override CFLAGS += \ + -march=rv64imac + else + override CFLAGS += \ + -march=rv64imac_zicsr_zifencei + endif + override CFLAGS += \ + -mabi=lp64 \ + -mno-relax + override LDFLAGS += \ + -Wl,-m,elf64lriscv \ + -Wl,--no-relax +endif +ifeq ($(ARCH),loongarch64) + ifeq ($(CC_IS_CLANG),1) + override CC += \ + -target loongarch64-unknown-none + endif + override CFLAGS += \ + -march=loongarch64 \ + -mabi=lp64s + override LDFLAGS += \ + -Wl,-m,elf64loongarch \ + -Wl,--no-relax +endif + +# Internal linker flags that should not be changed by the user. +override LDFLAGS += \ + -Wl,--build-id=none \ + -nostdlib \ + -static \ + -z max-page-size=0x1000 \ + -Wl,--gc-sections \ + -T linker-$(ARCH).ld + +# Use "find" to glob all *.c, *.S, and *.asm files in the tree and obtain the +# object and header dependency file names. +override SRCFILES := $(shell cd src && find -L * -type f | LC_ALL=C sort) +override CFILES := $(filter %.c,$(SRCFILES)) +override ASFILES := $(filter %.S,$(SRCFILES)) +ifeq ($(ARCH),x86_64) +override NASMFILES := $(filter %.asm,$(SRCFILES)) +endif +override OBJ := $(addprefix obj-$(ARCH)/,$(CFILES:.c=.c.o) $(ASFILES:.S=.S.o)) +ifeq ($(ARCH),x86_64) +override OBJ += $(addprefix obj-$(ARCH)/,$(NASMFILES:.asm=.asm.o)) +endif +override HEADER_DEPS := $(addprefix obj-$(ARCH)/,$(CFILES:.c=.c.d) $(ASFILES:.S=.S.d)) + +# Default target. This must come first, before header dependencies. +.PHONY: all +all: bin-$(ARCH)/$(OUTPUT) + +# Include header dependencies. +-include $(HEADER_DEPS) + +# Link rules for building the C compiler runtime. +cc-runtime-$(ARCH)/cc-runtime.a: GNUmakefile cc-runtime/* + rm -rf cc-runtime-$(ARCH) + cp -r cc-runtime cc-runtime-$(ARCH) + $(MAKE) -C cc-runtime-$(ARCH) -f cc-runtime.mk \ + CC="$(CC)" \ + AR="$(AR)" \ + CFLAGS="$(CFLAGS)" \ + CPPFLAGS='-isystem ../freestnd-c-hdrs -DCC_RUNTIME_NO_FLOAT' + +# Link rules for the final executable. +bin-$(ARCH)/$(OUTPUT): GNUmakefile linker-$(ARCH).ld $(OBJ) cc-runtime-$(ARCH)/cc-runtime.a + mkdir -p "$$(dirname $@)" + $(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) cc-runtime-$(ARCH)/cc-runtime.a -o $@ + +# Compilation rules for *.c files. +obj-$(ARCH)/%.c.o: src/%.c GNUmakefile + mkdir -p "$$(dirname $@)" + $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ + +# Compilation rules for *.S files. +obj-$(ARCH)/%.S.o: src/%.S GNUmakefile + mkdir -p "$$(dirname $@)" + $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ + +ifeq ($(ARCH),x86_64) +# Compilation rules for *.asm (nasm) files. +obj-$(ARCH)/%.asm.o: src/%.asm GNUmakefile + mkdir -p "$$(dirname $@)" + nasm $(NASMFLAGS) $< -o $@ +endif + +# Remove object files and the final executable. +.PHONY: clean +clean: + rm -rf bin-$(ARCH) obj-$(ARCH) cc-runtime-$(ARCH) + +# Remove everything built and generated including downloaded dependencies. +.PHONY: distclean +distclean: + rm -rf bin-* obj-* freestnd-c-hdrs cc-runtime* src/limine.h + +# Install the final built executable to its final on-root location. +.PHONY: install +install: all + install -d "$(DESTDIR)$(PREFIX)/share/$(OUTPUT)" + install -m 644 bin-$(ARCH)/$(OUTPUT) "$(DESTDIR)$(PREFIX)/share/$(OUTPUT)/$(OUTPUT)-$(ARCH)" + +# Try to undo whatever the "install" target did. +.PHONY: uninstall +uninstall: + rm -f "$(DESTDIR)$(PREFIX)/share/$(OUTPUT)/$(OUTPUT)-$(ARCH)" + -rmdir "$(DESTDIR)$(PREFIX)/share/$(OUTPUT)" diff --git a/kernel/get-deps b/kernel/get-deps new file mode 100755 index 0000000..97cf290 --- /dev/null +++ b/kernel/get-deps @@ -0,0 +1,80 @@ +#! /bin/sh + +set -ex + +srcdir="$(dirname "$0")" +test -z "$srcdir" && srcdir=. + +cd "$srcdir" + +clone_repo_commit() { + if test -d "$2/.git"; then + git -C "$2" reset --hard + git -C "$2" clean -fd + if ! git -C "$2" checkout $3; then + rm -rf "$2" + fi + else + if test -d "$2"; then + set +x + echo "error: '$2' is not a Git repository" + exit 1 + fi + fi + if ! test -d "$2"; then + git clone $1 "$2" + if ! git -C "$2" checkout $3; then + rm -rf "$2" + exit 1 + fi + fi +} + +download_by_hash() { + DOWNLOAD_COMMAND="curl -Lo" + if ! command -v $DOWNLOAD_COMMAND >/dev/null 2>&1; then + DOWNLOAD_COMMAND="wget -O" + if ! command -v $DOWNLOAD_COMMAND >/dev/null 2>&1; then + set +x + echo "error: Neither curl nor wget found" + exit 1 + fi + fi + SHA256_COMMAND="sha256sum" + if ! command -v $SHA256_COMMAND >/dev/null 2>&1; then + SHA256_COMMAND="sha256" + if ! command -v $SHA256_COMMAND >/dev/null 2>&1; then + set +x + echo "error: Cannot find sha256(sum) command" + exit 1 + fi + fi + if ! test -f "$2" || ! $SHA256_COMMAND "$2" | grep $3 >/dev/null 2>&1; then + rm -f "$2" + mkdir -p "$2" && rm -rf "$2" + $DOWNLOAD_COMMAND "$2" $1 + if ! $SHA256_COMMAND "$2" | grep $3 >/dev/null 2>&1; then + set +x + echo "error: Cannot download file '$2' by hash" + echo "incorrect hash:" + $SHA256_COMMAND "$2" + rm -f "$2" + exit 1 + fi + fi +} + +clone_repo_commit \ + https://github.com/osdev0/freestnd-c-hdrs-0bsd.git \ + freestnd-c-hdrs \ + a87c192f3eb66b0806740dc67325f9ad23fc2d0b + +clone_repo_commit \ + https://github.com/osdev0/cc-runtime.git \ + cc-runtime \ + 576a01179f3298a4795b92f42c088f9f8800b56b + +download_by_hash \ + https://github.com/limine-bootloader/limine/raw/4687a182be23939c2d9f15db970382dc353ed956/limine.h \ + src/limine.h \ + 6879e626f34c1be25ac2f72bf43b083fc2b53887280bb0fcdaee790e258c6974 diff --git a/kernel/linker-aarch64.ld b/kernel/linker-aarch64.ld new file mode 100755 index 0000000..e6dd67a --- /dev/null +++ b/kernel/linker-aarch64.ld @@ -0,0 +1,68 @@ +/* Tell the linker that we want an aarch64 ELF64 output file */ +OUTPUT_FORMAT(elf64-littleaarch64) + +/* We want the symbol kmain to be our entry point */ +ENTRY(kmain) + +/* Define the program headers we want so the bootloader gives us the right */ +/* MMU permissions; this also allows us to exert more control over the linking */ +/* process. */ +PHDRS +{ + limine_requests PT_LOAD; + text PT_LOAD; + rodata PT_LOAD; + data PT_LOAD; +} + +SECTIONS +{ + /* We want to be placed in the topmost 2GiB of the address space, for optimisations */ + /* and because that is what the Limine spec mandates. */ + /* Any address in this region will do, but often 0xffffffff80000000 is chosen as */ + /* that is the beginning of the region. */ + . = 0xffffffff80000000; + + /* Define a section to contain the Limine requests and assign it to its own PHDR */ + .limine_requests : { + KEEP(*(.limine_requests_start)) + KEEP(*(.limine_requests)) + KEEP(*(.limine_requests_end)) + } :limine_requests + + /* Move to the next memory page for .text */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .text : { + *(.text .text.*) + } :text + + /* Move to the next memory page for .rodata */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .rodata : { + *(.rodata .rodata.*) + } :rodata + + /* Move to the next memory page for .data */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .data : { + *(.data .data.*) + } :data + + /* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */ + /* unnecessary zeros will be written to the binary. */ + /* If you need, for example, .init_array and .fini_array, those should be placed */ + /* above this. */ + .bss : { + *(.bss .bss.*) + *(COMMON) + } :data + + /* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */ + /DISCARD/ : { + *(.eh_frame*) + *(.note .note.*) + } +} diff --git a/kernel/linker-loongarch64.ld b/kernel/linker-loongarch64.ld new file mode 100755 index 0000000..afd078e --- /dev/null +++ b/kernel/linker-loongarch64.ld @@ -0,0 +1,68 @@ +/* Tell the linker that we want a loongarch64 ELF64 output file */ +OUTPUT_FORMAT(elf64-loongarch) + +/* We want the symbol kmain to be our entry point */ +ENTRY(kmain) + +/* Define the program headers we want so the bootloader gives us the right */ +/* MMU permissions; this also allows us to exert more control over the linking */ +/* process. */ +PHDRS +{ + limine_requests PT_LOAD; + text PT_LOAD; + rodata PT_LOAD; + data PT_LOAD; +} + +SECTIONS +{ + /* We want to be placed in the topmost 2GiB of the address space, for optimisations */ + /* and because that is what the Limine spec mandates. */ + /* Any address in this region will do, but often 0xffffffff80000000 is chosen as */ + /* that is the beginning of the region. */ + . = 0xffffffff80000000; + + /* Define a section to contain the Limine requests and assign it to its own PHDR */ + .limine_requests : { + KEEP(*(.limine_requests_start)) + KEEP(*(.limine_requests)) + KEEP(*(.limine_requests_end)) + } :limine_requests + + /* Move to the next memory page for .text */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .text : { + *(.text .text.*) + } :text + + /* Move to the next memory page for .rodata */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .rodata : { + *(.rodata .rodata.*) + } :rodata + + /* Move to the next memory page for .data */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .data : { + *(.data .data.*) + } :data + + /* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */ + /* unnecessary zeros will be written to the binary. */ + /* If you need, for example, .init_array and .fini_array, those should be placed */ + /* above this. */ + .bss : { + *(.bss .bss.*) + *(COMMON) + } :data + + /* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */ + /DISCARD/ : { + *(.eh_frame*) + *(.note .note.*) + } +} diff --git a/kernel/linker-riscv64.ld b/kernel/linker-riscv64.ld new file mode 100755 index 0000000..52353cc --- /dev/null +++ b/kernel/linker-riscv64.ld @@ -0,0 +1,70 @@ +/* Tell the linker that we want a riscv64 ELF64 output file */ +OUTPUT_FORMAT(elf64-littleriscv) + +/* We want the symbol kmain to be our entry point */ +ENTRY(kmain) + +/* Define the program headers we want so the bootloader gives us the right */ +/* MMU permissions; this also allows us to exert more control over the linking */ +/* process. */ +PHDRS +{ + limine_requests PT_LOAD; + text PT_LOAD; + rodata PT_LOAD; + data PT_LOAD; +} + +SECTIONS +{ + /* We want to be placed in the topmost 2GiB of the address space, for optimisations */ + /* and because that is what the Limine spec mandates. */ + /* Any address in this region will do, but often 0xffffffff80000000 is chosen as */ + /* that is the beginning of the region. */ + . = 0xffffffff80000000; + + /* Define a section to contain the Limine requests and assign it to its own PHDR */ + .limine_requests : { + KEEP(*(.limine_requests_start)) + KEEP(*(.limine_requests)) + KEEP(*(.limine_requests_end)) + } :limine_requests + + /* Move to the next memory page for .text */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .text : { + *(.text .text.*) + } :text + + /* Move to the next memory page for .rodata */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .rodata : { + *(.rodata .rodata.*) + } :rodata + + /* Move to the next memory page for .data */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .data : { + *(.data .data.*) + *(.sdata .sdata.*) + } :data + + /* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */ + /* unnecessary zeros will be written to the binary. */ + /* If you need, for example, .init_array and .fini_array, those should be placed */ + /* above this. */ + .bss : { + *(.sbss .sbss.*) + *(.bss .bss.*) + *(COMMON) + } :data + + /* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */ + /DISCARD/ : { + *(.eh_frame*) + *(.note .note.*) + } +} diff --git a/kernel/linker-x86_64.ld b/kernel/linker-x86_64.ld new file mode 100755 index 0000000..8fe5465 --- /dev/null +++ b/kernel/linker-x86_64.ld @@ -0,0 +1,77 @@ +/* Tell the linker that we want an x86_64 ELF64 output file */ +OUTPUT_FORMAT(elf64-x86-64) + +/* We want the symbol kmain to be our entry point */ +ENTRY(kmain) + +/* Define the program headers we want so the bootloader gives us the right */ +/* MMU permissions; this also allows us to exert more control over the linking */ +/* process. */ +PHDRS +{ + limine_requests PT_LOAD; + text PT_LOAD; + rodata PT_LOAD; + data PT_LOAD; +} + +SECTIONS +{ + /* We want to be placed in the topmost 2GiB of the address space, for optimisations */ + /* and because that is what the Limine spec mandates. */ + /* Any address in this region will do, but often 0xffffffff80000000 is chosen as */ + /* that is the beginning of the region. */ + . = 0xffffffff80000000; + + + .text : { + text_start_ld = .; + *(.text .text.*) + text_end_ld = .; + } :text + + /* Move to the next memory page for .limine_requests */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + /* Define a section to contain the Limine requests and assign it to its own PHDR */ + .limine_requests : { + reqs_start_ld = .; + KEEP(*(.limine_requests_start)) + KEEP(*(.limine_requests)) + KEEP(*(.limine_requests_end)) + reqs_end_ld = .; + } :limine_requests + + /* Move to the next memory page for .rodata */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .rodata : { + rodata_start_ld = .; + *(.rodata .rodata.*) + rodata_end_ld = .; + } :rodata + + /* Move to the next memory page for .data */ + . = ALIGN(CONSTANT(MAXPAGESIZE)); + + .data : { + data_start_ld = .; + *(.data .data.*) + } :data + + /* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */ + /* unnecessary zeros will be written to the binary. */ + /* If you need, for example, .init_array and .fini_array, those should be placed */ + /* above this. */ + .bss : { + *(.bss .bss.*) + *(COMMON) + data_end_ld = .; + } :data + + /* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */ + /DISCARD/ : { + *(.eh_frame*) + *(.note .note.*) + } +} diff --git a/kernel/src/font.h b/kernel/src/font.h new file mode 100755 index 0000000..bdfa5b8 --- /dev/null +++ b/kernel/src/font.h @@ -0,0 +1,261 @@ +#pragma once + +// array size is 4096 +unsigned char VGA8[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, + 0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, + 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, + 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, 0x00, + 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, + 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, + 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, + 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, + 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; \ No newline at end of file diff --git a/kernel/src/main.c b/kernel/src/main.c new file mode 100755 index 0000000..b5b6fa0 --- /dev/null +++ b/kernel/src/main.c @@ -0,0 +1,124 @@ +#include "mm/pmm.h" +#include "mm/vmm.h" +#include "rt.h" +#include "sched/sched.h" +#include "sys/arch/x86_64/cpuid.h" +#include "sys/arch/x86_64/io.h" +#include "sys/arch/x86_64/pit.h" +#include "sys/arch/x86_64/rtc.h" +#include "sys/arch/x86_64/sse.h" +#include +#include +#include +#include +#include + +#include +#include +#include + +// Set the base revision to 3, this is recommended as this is the latest +// base revision described by the Limine boot protocol specification. +// See specification for further info. + +__attribute__((used, section(".limine_requests"))) +static volatile LIMINE_BASE_REVISION(3); + +// The Limine requests can be placed anywhere, but it is important that +// the compiler does not optimise them away, so, usually, they should +// be made volatile or equivalent, _and_ they should be accessed at least +// once or marked as used with the "used" attribute as done here. + +__attribute__((used, section(".limine_requests"))) +static volatile struct limine_framebuffer_request framebuffer_request = { + .id = LIMINE_FRAMEBUFFER_REQUEST, + .revision = 0 +}; + +/*__attribute__((used, section(".limine_requests"))) +static volatile struct limine_entry_point_request entrypoint_request = { + .id = LIMINE_ENTRY_POINT_REQUEST, + .revision = 3 +};*/ +// Finally, define the start and end markers for the Limine requests. +// These can also be moved anywhere, to any .c file, as seen fit. + +__attribute__((used, section(".limine_requests_start"))) +static volatile LIMINE_REQUESTS_START_MARKER; + +__attribute__((used, section(".limine_requests_end"))) +static volatile LIMINE_REQUESTS_END_MARKER; + + +// Halt and catch fire function. +static void hcf(void) { + for (;;) { +#if defined (__x86_64__) + asm ("hlt"); +#elif defined (__aarch64__) || defined (__riscv) + asm ("wfi"); +#elif defined (__loongarch64) + asm ("idle 0"); +#endif + } +} + +int init() { + asm("int $0x80"); + while (1) + ;; +} + +struct limine_framebuffer *fb; + +// The following will be our kernel's entry point. +// If renaming kmain() to something else, make sure to change the +// linker script accordingly. +void kmain(void) { + // Ensure the bootloader actually understands our base revision (see spec). + if (LIMINE_BASE_REVISION_SUPPORTED == false) { + hcf(); + } + + // Ensure we got a framebuffer. + if (framebuffer_request.response == NULL + || framebuffer_request.response->framebuffer_count < 1) { + hcf(); + } + + // Fetch the first framebuffer. + struct limine_framebuffer *framebuffer = framebuffer_request.response->framebuffers[0]; + fb = framebuffer; + + rt_context ctx; + ctx.framebuffer = fb->address; + ctx.framebuffer_width = fb->width; + ctx.framebuffer_height = fb->height; + rt_init(ctx); + + printf("\n Soaplin 1.0-sild is booting up your computer...\n\n"); + //printf("Physical kernel EP: %p", entrypoint_request.entry); + + gdt_init(); + idt_init(); + + sse_init(); + + pmm_init(); + vmm_init(); + + pit_init(1000); + sched_init(); + + uint64_t *mem = pmm_request_page(); + mem[0] = 0xCD; + mem[1] = 0x80; + mem[2] = 0xFE; + mem[3] = 0xEB; + sched_process *proc = sched_create("Init", 0x1000, SCHED_USER_PROCESS); + vmm_map(proc->pm, 0x1000, (uint64_t)mem, VMM_PRESENT | VMM_USER); + + log("kernel - Soaplin initialized sucessfully.\n"); + while (1) + ;;//__asm__ volatile ("hlt"); +} diff --git a/kernel/src/mm/memop.c b/kernel/src/mm/memop.c new file mode 100755 index 0000000..dca421b --- /dev/null +++ b/kernel/src/mm/memop.c @@ -0,0 +1,59 @@ +// Copyright (C) 2024 Sipaa Projects +// This code is part of the Soaplin kernel and is licensed under the terms of +// the MIT License. + +#include "mm/pmm.h" +#include +#include + +void *memcpy(void *dest, const void *src, size_t n) { + uint8_t *pdest = (uint8_t *)dest; + const uint8_t *psrc = (const uint8_t *)src; + + + for (size_t i = 0; i < n; i++) { + pdest[i] = psrc[i]; + } + + return dest; +} + +void *memset(void *s, int c, size_t n) { + uint8_t *p = (uint8_t *)s; + + for (size_t i = 0; i < n; i++) { + p[i] = (uint8_t)c; + } + + return s; +} + +void *memmove(void *dest, const void *src, size_t n) { + uint8_t *pdest = (uint8_t *)dest; + const uint8_t *psrc = (const uint8_t *)src; + + if (src > dest) { + for (size_t i = 0; i < n; i++) { + pdest[i] = psrc[i]; + } + } else if (src < dest) { + for (size_t i = n; i > 0; i--) { + pdest[i - 1] = psrc[i - 1]; + } + } + + return dest; +} + +int memcmp(const void *s1, const void *s2, size_t n) { + const uint8_t *p1 = (const uint8_t *)s1; + const uint8_t *p2 = (const uint8_t *)s2; + + for (size_t i = 0; i < n; i++) { + if (p1[i] != p2[i]) { + return p1[i] < p2[i] ? -1 : 1; + } + } + + return 0; +} \ No newline at end of file diff --git a/kernel/src/mm/memop.h b/kernel/src/mm/memop.h new file mode 100755 index 0000000..7a62f7e --- /dev/null +++ b/kernel/src/mm/memop.h @@ -0,0 +1,13 @@ +// Copyright (C) 2024 Sipaa Projects +// This code is part of the Soaplin kernel and is licensed under the terms of +// the MIT License. + +#pragma once + +#include +#include + +void *memcpy(void *dest, const void *src, size_t n); +void *memset(void *s, int c, size_t n); +void *memmove(void *dest, const void *src, size_t n); +int memcmp(const void *s1, const void *s2, size_t n); \ No newline at end of file diff --git a/kernel/src/mm/pmm.c b/kernel/src/mm/pmm.c new file mode 100755 index 0000000..ebccb22 --- /dev/null +++ b/kernel/src/mm/pmm.c @@ -0,0 +1,114 @@ +#include "limine.h" +#include +#include +#include +#include +#include + +pmm_stack_t stack; +struct limine_memmap_response *_memmap; + +uint64_t hhdm_offset = 0x0; + +__attribute__((used, section(".limine_requests"))) +struct limine_memmap_request mm_req = { + .id = LIMINE_MEMMAP_REQUEST, + .revision = 3 +}; + + +__attribute__((used, section(".limine_requests"))) +struct limine_hhdm_request hhdm_req = { + .id = LIMINE_HHDM_REQUEST, + .revision = 3 +}; + +int pmm_init() +{ + uint64_t free_pages = 0; + hhdm_offset = hhdm_req.response->offset; + + struct limine_memmap_response *memmap = mm_req.response; + _memmap = memmap; + + //DEBUG("mm", "----- PMM //INFO -----"); + int freemem = 0; + for (uint64_t i = 0; i < memmap->entry_count; i++) + { + if (memmap->entries[i]->type == LIMINE_MEMMAP_USABLE) + { + //DEBUG("mm", " - USABLE ENTRY\t\t@ 0x%.16llx, size: 0x%.16llx", memmap->entries[i]->base, memmap->entries[i]->length); + free_pages += DIV_ROUND_UP(memmap->entries[i]->length, PMM_PAGE_SIZE); + freemem += memmap->entries[i]->length; + } + } + + uint64_t array_size = ALIGN_UP(free_pages * 8, PMM_PAGE_SIZE); + + for (uint64_t i = 0; i < memmap->entry_count; i++) + { + struct limine_memmap_entry *entry = memmap->entries[i]; + if (entry->length >= array_size && entry->type == LIMINE_MEMMAP_USABLE) + { + stack.pages = (uintptr_t*)HIGHER_HALF(entry->base); + entry->length -= array_size; + entry->base += array_size; + //DEBUG("mm", " - STACK START\t\t@ 0x%.16llx", stack.pages); + break; + } + } + + for (uint64_t i = 0; i < memmap->entry_count; i++) + { + struct limine_memmap_entry *entry = memmap->entries[i]; + if (entry->type == LIMINE_MEMMAP_USABLE) + { + for (uint64_t j = 0; j < entry->length; j += PMM_PAGE_SIZE) + { + stack.pages[stack.idx++] = entry->base + j; + } + } + } + + stack.max = stack.idx; + //DEBUG("mm", " - MAX INDEX:\t\t%d", stack.max); + //DEBUG("mm", " - CURRENT INDEX:\t%d", stack.idx); + //DEBUG("mm", "--------------------"); + + + log("pmm - %dmb is available to us.\n", freemem / (1024 * 1024)); + return 0; +} + +void *pmm_request_page() +{ + if (stack.idx == 0) + { + //ERROR("mm", "No more pages available."); + log("pmm - out of memory.\n"); + asm("cli"); + while (1) { + asm("hlt"); + } + return NULL; + } + + uint64_t page_addr = stack.pages[--stack.idx]; + memset(HIGHER_HALF(page_addr), 0, PMM_PAGE_SIZE); + return (void *)page_addr; +} + +void pmm_free_page(void *ptr) +{ + if (ptr == NULL) + return; + + if (stack.idx >= stack.max) + { + //ERROR("mm", "Stack overflow attempt while freeing a page."); + log("pmm - could not free the page: stack overflow.\n"); + return; + } + + stack.pages[stack.idx++] = (uint64_t)ptr; +} \ No newline at end of file diff --git a/kernel/src/mm/pmm.h b/kernel/src/mm/pmm.h new file mode 100755 index 0000000..f39a988 --- /dev/null +++ b/kernel/src/mm/pmm.h @@ -0,0 +1,28 @@ +#ifndef PMM_H +#define PMM_H + +#include +#define PMM_PAGE_SIZE 4096 + +typedef struct pmm_stack +{ + uintptr_t *pages; + uint64_t idx; + uint64_t max; +} pmm_stack_t; + +extern uint64_t hhdm_offset; + +#define DIV_ROUND_UP(x, y) (((uint64_t)(x) + ((uint64_t)(y) - 1)) / (uint64_t)(y)) +#define ALIGN_UP(x, y) (DIV_ROUND_UP(x, y) * (uint64_t)(y)) +#define ALIGN_DOWN(x, y) (((uint64_t)(x) / (uint64_t)(y)) * (uint64_t)(y)) + +#define HIGHER_HALF(ptr) ((void *)((uint64_t)ptr) + hhdm_offset) +#define PHYSICAL(ptr) ((void *)((uint64_t)ptr) - hhdm_offset) + +int pmm_init(); +void *pmm_request_page(); +void pmm_free_page(void *ptr); +void pmm_dump(); + +#endif // PMM_H \ No newline at end of file diff --git a/kernel/src/mm/vmm.c b/kernel/src/mm/vmm.c new file mode 100755 index 0000000..6d905e2 --- /dev/null +++ b/kernel/src/mm/vmm.c @@ -0,0 +1,187 @@ +#include "mm/vmm.h" +#include "limine.h" +#include "mm/pmm.h" +#include "mm/memop.h" +#include "sys/log.h" +#include + + +__attribute__((used, section(".limine_requests"))) +static volatile struct limine_paging_mode_request pmrq = { + .id = LIMINE_PAGING_MODE_REQUEST, + .revision = 3, + .mode = LIMINE_PAGING_MODE_X86_64_4LVL +}; + +__attribute__((used, section(".limine_requests"))) +static volatile struct limine_executable_address_request karq = { + .id = LIMINE_EXECUTABLE_ADDRESS_REQUEST, + .revision = 0, +}; + +pagemap_t *vmm_kernel_pm = NULL; +pagemap_t *vmm_current_pm = NULL; +int vmm_kernel_pm_exists = 0; + +pagemap_t *vmm_alloc_pm() { + pagemap_t *pm = (pagemap_t*)HIGHER_HALF((uint64_t)pmm_request_page()); + memset(pm, 0, PMM_PAGE_SIZE); + + + /*if (vmm_kernel_pm_exists) { + pm->toplevel = (uint64_t*)HIGHER_HALF((uint64_t)pmm_request_page()); + memset(pm->toplevel, 0, PMM_PAGE_SIZE); + + for (int i = 256; i < 512; i++) { + pm->toplevel[i] = vmm_kernel_pm->toplevel[i]; + } + } else { + + __asm__ volatile("mov %%cr3, %0" : "=r"(pm->toplevel) : : "memory"); + pm->toplevel = HIGHER_HALF(pm->toplevel); + logln(info, "vmm", "Limine-provided kernel PML4: %p", pm->toplevel); + + }*/ + + pm->toplevel = (uint64_t*)HIGHER_HALF((uint64_t)pmm_request_page()); + memset(pm->toplevel, 0, PMM_PAGE_SIZE); + + if (vmm_kernel_pm_exists) { + for (int i = 256; i < 512; i++) { + pm->toplevel[i] = vmm_kernel_pm->toplevel[i]; + } + } + + return pm; +} + +void vmm_release_pm(pagemap_t *pm) { + memset(pm->toplevel, 0, PMM_PAGE_SIZE); + memset(pm, 0, PMM_PAGE_SIZE); + pmm_free_page(pm->toplevel); + pmm_free_page(pm); +} + +void vmm_sanity_check() { + uint64_t *my_memory = pmm_request_page(); + *my_memory = 0x40; + + pagemap_t *pm = vmm_alloc_pm(); + vmm_map(pm, 0x1000, (uint64_t)my_memory, VMM_PRESENT | VMM_WRITABLE); + + uint64_t *my_ptr = (uint64_t*)0x1000; + uint64_t ptr_val = 0; + vmm_load_pagemap(pm); + ptr_val = *my_ptr; + vmm_load_pagemap(vmm_kernel_pm); + + if (ptr_val != 0x40) { + log("vmm - sanity check failed. system halted.\n"); + asm("cli"); + while (1) + asm("hlt"); + } +} + +void vmm_init() { + if (pmrq.response->mode != LIMINE_PAGING_MODE_X86_64_4LVL) { + log("vmm - Soaplin only supports 4-level paging!\n"); + asm("cli; hlt;"); + } + vmm_kernel_pm = vmm_alloc_pm(); + vmm_kernel_pm_exists = 1; + + uint64_t kphysaddr = karq.response->physical_base; + uint64_t kvirtaddr = karq.response->virtual_base; + + uint64_t reqs_start = ALIGN_DOWN((uint64_t)reqs_start_ld, PMM_PAGE_SIZE); + uint64_t reqs_end = ALIGN_UP((uint64_t)reqs_end_ld, PMM_PAGE_SIZE); + uint64_t text_start = ALIGN_DOWN((uint64_t)text_start_ld, PMM_PAGE_SIZE); + uint64_t text_end = ALIGN_UP((uint64_t)text_end_ld, PMM_PAGE_SIZE); + uint64_t rodata_start = ALIGN_DOWN((uint64_t)rodata_start_ld, PMM_PAGE_SIZE); + uint64_t rodata_end = ALIGN_UP((uint64_t)rodata_end_ld, PMM_PAGE_SIZE); + uint64_t data_start = ALIGN_DOWN((uint64_t)data_start_ld, PMM_PAGE_SIZE); + uint64_t data_end = ALIGN_UP((uint64_t)data_end_ld, PMM_PAGE_SIZE); + + + log("vmm - mapping .requests section...\n"); + for (uint64_t req = reqs_start; req < reqs_end; req += PMM_PAGE_SIZE) { + vmm_map(vmm_kernel_pm, req, req - kvirtaddr + kphysaddr, VMM_PRESENT | VMM_WRITABLE); + } + + log("vmm - mapping .text section...\n"); + for (uint64_t text = text_start; text < text_end; text += PMM_PAGE_SIZE) { + vmm_map(vmm_kernel_pm, text, text - kvirtaddr + kphysaddr, VMM_PRESENT); + } + + log("vmm - mapping .rodata section...\n"); + for (uint64_t roData = rodata_start; roData < rodata_end; roData += PMM_PAGE_SIZE) + vmm_map(vmm_kernel_pm, roData, roData - kvirtaddr + kphysaddr, + VMM_PRESENT | VMM_NX); + + log("vmm - mapping .data section...\n"); + for (uint64_t data = data_start; data < data_end; data += PMM_PAGE_SIZE) + vmm_map(vmm_kernel_pm, data, data - kvirtaddr + kphysaddr, + VMM_PRESENT | VMM_WRITABLE | VMM_NX); + + log("vmm - mapping address from 0x0 to 0x100000000...\n"); + for (uint64_t gb4 = 0; gb4 < 0x100000000; gb4 += PMM_PAGE_SIZE) { + vmm_map(vmm_kernel_pm, gb4, gb4, VMM_PRESENT | VMM_WRITABLE); + vmm_map(vmm_kernel_pm, (uint64_t)HIGHER_HALF(gb4), gb4, VMM_PRESENT | VMM_WRITABLE); + } + + vmm_load_pagemap(vmm_kernel_pm); + + vmm_sanity_check(); + log("vmm - initialized!\n"); +} + +void vmm_load_pagemap(pagemap_t *pm) { + if (!pm) + return; + + if (!pm->toplevel) + return; + + vmm_current_pm = pm; + __asm__ volatile("mov %0, %%cr3" : : "r"(PHYSICAL(pm->toplevel)) : "memory"); +} + +static uint64_t *__vmm_get_next_lvl(uint64_t *level, uint64_t entry, uint64_t flags) { + if (level[entry] & 1) + return HIGHER_HALF(PTE_GET_ADDR(level[entry])); + uint64_t *pml = HIGHER_HALF(pmm_request_page()); + memset(pml, 0, PMM_PAGE_SIZE); + level[entry] = (uint64_t)PHYSICAL(pml) | (flags & 0xFFF); // N'ajoute que les flags pertinents + return pml; +} + +void vmm_map(pagemap_t *pm, uint64_t vaddr, uint64_t paddr, uint64_t flags) { + uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; + uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; + uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; + uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; + + uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, flags); + uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, flags); + uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, flags); + + pml1[pml1_entry] = paddr | flags; +} +void vmm_unmap(pagemap_t *pm, uint64_t vaddr) { + uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; + uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; + uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; + uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; + + uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, 0); + if (pml3 == NULL) return; + uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, 0); + if (pml2 == NULL) return; + uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, 0); + if (pml1 == NULL) return; + + pml1[pml1_entry] = 0; + + __asm__ volatile ("invlpg (%0)" : : "b"(vaddr) : "memory"); +} \ No newline at end of file diff --git a/kernel/src/mm/vmm.h b/kernel/src/mm/vmm.h new file mode 100755 index 0000000..97239b4 --- /dev/null +++ b/kernel/src/mm/vmm.h @@ -0,0 +1,41 @@ +#pragma once + +#include + +#define PTE_ADDR_MASK 0x000ffffffffff000 +#define PTE_GET_ADDR(VALUE) ((VALUE) & PTE_ADDR_MASK) +#define PTE_GET_FLAGS(VALUE) ((VALUE) & ~PTE_ADDR_MASK) + +#define VMM_PRESENT (1 << 0) +#define VMM_WRITABLE (1 << 1) +#define VMM_USER (1 << 2) +#define VMM_NX (1ULL << 63) + +typedef char sym[]; + +extern sym reqs_start_ld; +extern sym reqs_end_ld; + +extern sym text_start_ld; +extern sym text_end_ld; + +extern sym rodata_start_ld; +extern sym rodata_end_ld; + +extern sym data_start_ld; +extern sym data_end_ld; + + +typedef struct pagemap { + uint64_t *toplevel; +} pagemap_t; + +extern pagemap_t *vmm_kernel_pm; +extern pagemap_t *vmm_current_pm; + +pagemap_t *vmm_alloc_pm(); +void vmm_init(); +void vmm_release_pm(pagemap_t *pm); +void vmm_load_pagemap(pagemap_t *pm); +void vmm_map(pagemap_t *pm, uint64_t vaddr, uint64_t paddr, uint64_t flags); +void vmm_unmap(pagemap_t *pm, uint64_t vaddr) ; \ No newline at end of file diff --git a/kernel/src/rt.c b/kernel/src/rt.c new file mode 100755 index 0000000..afec901 --- /dev/null +++ b/kernel/src/rt.c @@ -0,0 +1,85 @@ +#include "rt.h" +#include +#include +#include + +static rt_context _curctx; + +void _rt_drawchar(unsigned char c, int x, int y, int fgcolor, int bgcolor) +{ + int cx,cy; + int mask[8]={128, 64, 32, 16, 8, 4, 2, 1}; + unsigned char *glyph=VGA8+(int)c*16; + + uint32_t *buf = _curctx.framebuffer; + + for(cy=0;cy<16;cy++){ + for(cx=0;cx<8;cx++){ + buf[((y + cy) * _curctx.framebuffer_width) + (x + cx)] = glyph[cy]&mask[cx]?fgcolor:bgcolor; + } + } +} +void _rt_draw_fillchar(int x, int y, int bgcolor, int fgcolor) { + int cx,cy; + uint32_t *buf = _curctx.framebuffer; + for(cy=0;cy<16;cy++){ + for(cx=0;cx<8;cx++){ + buf[((y + cy) * _curctx.framebuffer_width) + (x + cx)] = cy > 12 ? fgcolor : bgcolor; + } + } +} + +int _rt_strlen(char *str) { + int i = 0; + while (str[i] != '\0') i++; + return i; +} + +void rt_init(rt_context ctx) { + // Copy the structure + char *src = (char*)&ctx; + char *dst = (char*)&_curctx; + for (unsigned long i = 0; i < sizeof(rt_context); i++) { + dst[i] = src[i]; + } + + // Fill fields + _curctx.term_width = _curctx.framebuffer_width / 8; + _curctx.term_height = _curctx.framebuffer_height / 16; +} + +void rt_print(char *str) { + _rt_draw_fillchar(_curctx.x * 8, _curctx.y * 16, 0x0, 0x0); + + for (int i = 0; i < _rt_strlen(str); i++) { + if (str[i] == '\n' && _curctx.use_crlf_ending) + if (_curctx.y * 16 >= _curctx.framebuffer_height) { + _curctx.y = 0; + memset( + _curctx.framebuffer, _curctx.bg_color, + _curctx.framebuffer_width * _curctx.framebuffer_height * sizeof(uint32_t)); + } else { + _curctx.y++; + } + else if (str[i] == '\n') + { + if (_curctx.y * 16 >= _curctx.framebuffer_height) { + _curctx.y = 0; + memset( + _curctx.framebuffer, _curctx.bg_color, + _curctx.framebuffer_width * _curctx.framebuffer_height * sizeof(uint32_t)); + } else { + _curctx.y++; + } + _curctx.x = 0; + } + else if (str[i] == '\r') + _curctx.x = 0; + else { + _rt_drawchar(str[i], _curctx.x * 8, _curctx.y * 16, 0xFFFFFF, 0x0); + _curctx.x++; + } + } + + _rt_draw_fillchar(_curctx.x * 8, _curctx.y * 16, 0x0, 0xFFFFFF); +} \ No newline at end of file diff --git a/kernel/src/rt.h b/kernel/src/rt.h new file mode 100755 index 0000000..fcd601c --- /dev/null +++ b/kernel/src/rt.h @@ -0,0 +1,41 @@ +#pragma once + +#include + +typedef struct _rt_ctx { + // A pointer to the framebuffer. + void *framebuffer; + + // The framebuffer width, in pixels. + uint32_t framebuffer_width; + + // The framebuffer height, in pixels. + uint32_t framebuffer_height; + + // Set this to 1 if you prefer using DOS line endings to UNIX line endings. + int use_crlf_ending; + + // Do we need to show a cursor after printing text? + int show_cursor; + + // The background color + uint32_t bg_color; + + // The foreground color + uint32_t fg_color; + + /* + * Do NOT modify everything below me! + */ + // The terminal's width, in columns of 8 pixels. + int term_width; + // The terminal's height, in rows of 16 pixels. + int term_height; + // The X position of the cursor, in columns of 8 pixels. + int x; + // The Y position of the cursor, in rows of 16 pixels. + int y; +} rt_context; + +void rt_init(rt_context ctx); +void rt_print(char *str); \ No newline at end of file diff --git a/kernel/src/sched/sched.c b/kernel/src/sched/sched.c new file mode 100755 index 0000000..b39c2fc --- /dev/null +++ b/kernel/src/sched/sched.c @@ -0,0 +1,111 @@ +#include "sched/sched.h" +#include "mm/pmm.h" +#include "mm/memop.h" +#include "mm/vmm.h" +#include "sys/arch/x86_64/idt.h" +#include "sys/log.h" +#include + +sched_process *proc_list; +sched_process *curr_proc; +int current_pid = 0; +int standby = 0; + +void sched_init() { + // TODO: It may be good to implement heap memory to save space. + + // We must initialize the process list. + // By default, sched_create will append to this list. + proc_list = pmm_request_page(); + memcpy(proc_list->name, "System\0", 7); + proc_list->pid = -1; + proc_list->type = SCHED_EMPTY; + + curr_proc = proc_list; + + standby = 1; + log("sched - As there's nothing " + "to schedule, the scheduler entered standby" + "mode.\n"); +} + +sched_process *sched_create(char *name, uint64_t entry_point, uint32_t flags) +{ + // TODO: implement a separate strlen function + // as there's like 4 strlen impls in the kernel. + int i = 0; + while (name[i] != 0) + i++; + + sched_process *proc = pmm_request_page(); + memset(proc, 0, sizeof(sched_process)); + + memcpy(proc->name, name, i); + proc->pid = current_pid; + proc->type = SCHED_RUNNING; + + // We are about to setup the registers ourself. + // If it's broken, it's a boom in the ass of your computer + // (and a CPU exception) + + proc->pm = vmm_alloc_pm(); + + uint64_t *stack_phys = pmm_request_page(); + uint64_t *stack_virt = (uint64_t*)0x40000000; + + if (flags == SCHED_KERNEL_PROCESS) { + proc->stack_base = stack_phys; + proc->stack_end = proc_list->stack_base + PMM_PAGE_SIZE; + } else if (flags == SCHED_USER_PROCESS) { + vmm_map(proc->pm, (uint64_t)stack_virt, (uint64_t)stack_phys, VMM_PRESENT | VMM_WRITABLE | VMM_USER); + proc->stack_base = stack_virt; + proc->stack_end = proc_list->stack_base + PMM_PAGE_SIZE; + } + proc->regs.rip = (uint64_t)entry_point; + + if (flags == SCHED_KERNEL_PROCESS) { + proc->regs.cs = 0x28; // Run in kernel mode + proc->regs.ss = 0x30; + } + else if (flags == SCHED_USER_PROCESS) { + proc->regs.cs = 0x43; // Run in kernel mode + proc->regs.ss = 0x3B; + } + proc->regs.rflags = 0x202; // Enable interrupts + proc->regs.rsp = (uint64_t)proc->stack_end; + proc->regs.rbp = 0; + + proc->next = curr_proc->next; + curr_proc->next = proc; + + current_pid++; + + if (standby) { + // Disable standby mode as there's actually something to + // run, now. + standby = 0; + log("sched - Standby mode has been" + "disabled.\n"); + } + return proc; +} + +void schedule(registers_t *regs) +{ + if (standby) { + //log("sched - Sched is in standby.\n"); + return; + } + + memcpy(&curr_proc->regs, regs, sizeof(registers_t)); + + curr_proc = curr_proc->next; + if (curr_proc == NULL) + curr_proc = proc_list; + + //log("sched - I choosed process %d\n", curr_proc->pid); + memcpy(regs, &curr_proc->regs, sizeof(registers_t)); + + // Finally, load our pagemap + //vmm_load_pagemap(curr_proc->pm); +} \ No newline at end of file diff --git a/kernel/src/sched/sched.h b/kernel/src/sched/sched.h new file mode 100755 index 0000000..f5d2b04 --- /dev/null +++ b/kernel/src/sched/sched.h @@ -0,0 +1,39 @@ +#pragma once + +#include "mm/vmm.h" +#include "sys/arch/x86_64/idt.h" + +#define SCHED_KERNEL_PROCESS 0 // A process that runs in kernel mode. +#define SCHED_USER_PROCESS 1 // A process that runs in userspace. The code MUST be mapped directly after creating the process. + +typedef enum { + SCHED_RUNNING, + SCHED_EXITED, + SCHED_EMPTY +} sched_proc_type; + +typedef struct _sched_process { + char name[128]; + int pid; + int type; + + registers_t regs; + pagemap_t *pm; + + uint64_t *stack_end; + uint64_t *stack_base; + + struct _sched_process *next; +} sched_process; + +extern sched_process *curr_proc; +extern sched_process *proc_list; + +// The idle process is ditched in favor of standby mode, +// which activates when there's nothing to run. +//extern sched_process *idle_process; + +void sched_init(); +sched_process *sched_create(char *name, uint64_t entry_point, uint32_t flags); +void sched_exit(sched_process *proc); +void schedule(registers_t *regs); \ No newline at end of file diff --git a/kernel/src/sys/arch/arch.h b/kernel/src/sys/arch/arch.h new file mode 100755 index 0000000..284f561 --- /dev/null +++ b/kernel/src/sys/arch/arch.h @@ -0,0 +1,5 @@ +#pragma once + +#define ENSURE_X86_64 #ifdef __x86_64__ + +#define ENDENSURE \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/cpuid.h b/kernel/src/sys/arch/x86_64/cpuid.h new file mode 100755 index 0000000..021f89e --- /dev/null +++ b/kernel/src/sys/arch/x86_64/cpuid.h @@ -0,0 +1,637 @@ +#ifndef __CPUID_H__ +#define __CPUID_H__ + +#include + +//=================CPUID_VENDOR================= +#define CPUID_VENDOR_INTEL "GenuineIntel" +#define CPUID_VENDOR_AMD "AuthenticAMD" + +//================CPUID_CPU_INFO================ +#define CPUID_CPU_INFO_EAX_STEPPING_MASK 0xF +#define CPUID_CPU_INFO_EAX_MODEL_MASK 0xF << 4 +#define CPUID_CPU_INFO_EAX_FAMILY_MASK 0xF << 8 +#define CPUID_CPU_INFO_EAX_TYPE_MASK 0x3 << 12 +#define CPUID_CPU_INFO_EAX_EXT_MODEL_MASK 0xF << 16 +#define CPUID_CPU_INFO_EAX_EXT_FAMILY_MASK 0xFF << 20 + +#define CPUID_CPU_INFO_EBX_BRAND_INDEX 0xFF +#define CPUID_CPU_INFO_EBX_CFLUSH_SIZE 0xFF << 8 +#define CPUID_CPU_INFO_EBX_MAX_LOGPROC 0xFF << 16 +#define CPUID_CPU_INFO_EBX_INIT_APIC_ID 0xFF << 25 + +#define CPUID_CPU_INFO_ECX_SSE3 1 << 0 +#define CPUID_CPU_INFO_ECX_PCLMULQDQ 1 << 1 +#define CPUID_CPU_INFO_ECX_DTES64 1 << 2 +#define CPUID_CPU_INFO_ECX_MONITOR 1 << 3 +#define CPUID_CPU_INFO_ECX_DS_CPL 1 << 4 +#define CPUID_CPU_INFO_ECX_VMX 1 << 5 +#define CPUID_CPU_INFO_ECX_SMX 1 << 6 +#define CPUID_CPU_INFO_ECX_EIST 1 << 7 +#define CPUID_CPU_INFO_ECX_TM2 1 << 8 +#define CPUID_CPU_INFO_ECX_SSSE3 1 << 9 +#define CPUID_CPU_INFO_ECX_CNXT_ID 1 << 10 +#define CPUID_CPU_INFO_ECX_SDBG 1 << 11 +#define CPUID_CPU_INFO_ECX_FMA 1 << 12 +#define CPUID_CPU_INFO_ECX_CMPXCHG16B 1 << 13 +#define CPUID_CPU_INFO_ECX_XTPR_UC 1 << 14 +#define CPUID_CPU_INFO_ECX_PDCM 1 << 15 +//bit 16 is reserved +#define CPUID_CPU_INFO_ECX_PCID 1 << 17 +#define CPUID_CPU_INFO_ECX_DCA 1 << 18 +#define CPUID_CPU_INFO_ECX_SSE4_1 1 << 19 +#define CPUID_CPU_INFO_ECX_SSE4_2 1 << 20 +#define CPUID_CPU_INFO_ECX_X2APIC 1 << 21 +#define CPUID_CPU_INFO_ECX_MOVBE 1 << 22 +#define CPUID_CPU_INFO_ECX_POPCNT 1 << 23 +#define CPUID_CPU_INFO_ECX_TSC_DEADLINE 1 << 24 +#define CPUID_CPU_INFO_ECX_AESNI 1 << 25 +#define CPUID_CPU_INFO_ECX_XSAVE 1 << 26 +#define CPUID_CPU_INFO_ECX_OSXSAVE 1 << 27 +#define CPUID_CPU_INFO_ECX_AVX 1 << 28 +#define CPUID_CPU_INFO_ECX_F16C 1 << 29 +#define CPUID_CPU_INFO_ECX_RDRAND 1 << 30 +//bit 31 is unused + +#define CPUID_CPU_INFO_EDX_FPU 1 << 0 +#define CPUID_CPU_INFO_EDX_VME 1 << 1 +#define CPUID_CPU_INFO_EDX_DE 1 << 2 +#define CPUID_CPU_INFO_EDX_PSE 1 << 3 +#define CPUID_CPU_INFO_EDX_TSC 1 << 4 +#define CPUID_CPU_INFO_EDX_MSR 1 << 5 +#define CPUID_CPU_INFO_EDX_PAE 1 << 6 +#define CPUID_CPU_INFO_EDX_MCE 1 << 7 +#define CPUID_CPU_INFO_EDX_CX8 1 << 8 +#define CPUID_CPU_INFO_EDX_APIC 1 << 9 +//bit 10 is reserved +#define CPUID_CPU_INFO_EDX_SEP 1 << 11 +#define CPUID_CPU_INFO_EDX_MTRR 1 << 12 +#define CPUID_CPU_INFO_EDX_PGE 1 << 13 +#define CPUID_CPU_INFO_EDX_MCA 1 << 14 +#define CPUID_CPU_INFO_EDX_CMOV 1 << 15 +#define CPUID_CPU_INFO_EDX_PAT 1 << 16 +#define CPUID_CPU_INFO_EDX_PSE_36 1 << 17 +#define CPUID_CPU_INFO_EDX_PSN 1 << 18 +#define CPUID_CPU_INFO_EDX_CLFSH 1 << 19 +//bit 20 is reserved +#define CPUID_CPU_INFO_EDX_DS 1 << 21 +#define CPUID_CPU_INFO_EDX_ACPI 1 << 22 +#define CPUID_CPU_INFO_EDX_MMX 1 << 23 +#define CPUID_CPU_INFO_EDX_FXSR 1 << 24 +#define CPUID_CPU_INFO_EDX_SSE 1 << 25 +#define CPUID_CPU_INFO_EDX_SSE2 1 << 26 +#define CPUID_CPU_INFO_EDX_SS 1 << 27 +#define CPUID_CPU_INFO_EDX_HTT 1 << 28 +#define CPUID_CPU_INFO_EDX_TM 1 << 29 +//bit 30 is reserved +#define CPUID_CPU_INFO_EDX_PBE 1 << 31 + +//===============CPUID_CACHE_TLB=============== +//WARNING: I gave up and used ChatGPT for these +#define CPUID_CACHE_TLB_DESC_NULL 0x00 +#define CPUID_CACHE_TLB_DESC_TLB_4_KBYTE_4WAY_32E 0x01 +#define CPUID_CACHE_TLB_DESC_TLB_4_MBYTE_FULLY_2E 0x02 +#define CPUID_CACHE_TLB_DESC_DTLB_4_KBYTE_4WAY_64E 0x03 +#define CPUID_CACHE_TLB_DESC_DTLB_4_MBYTE_4WAY_8E 0x04 +#define CPUID_CACHE_TLB_DESC_DTLB1_4_MBYTE_4WAY_32E 0x05 +#define CPUID_CACHE_TLB_DESC_L1_INST_8K_4WAY_32B 0x06 +#define CPUID_CACHE_TLB_DESC_L1_INST_16K_4WAY_32B 0x08 +#define CPUID_CACHE_TLB_DESC_L1_INST_32K_4WAY_64B 0x09 +#define CPUID_CACHE_TLB_DESC_L1_DATA_8K_2WAY_32B 0x0A +#define CPUID_CACHE_TLB_DESC_TLB_4_MBYTE_4WAY_4E 0x0B +#define CPUID_CACHE_TLB_DESC_L1_DATA_16K_4WAY_32B 0x0C +#define CPUID_CACHE_TLB_DESC_L1_DATA_16K_4WAY_64B 0x0D +#define CPUID_CACHE_TLB_DESC_L1_DATA_24K_6WAY_64B 0x0E +#define CPUID_CACHE_TLB_DESC_L2_128K_2WAY_64B 0x1D +#define CPUID_CACHE_TLB_DESC_L2_256K_8WAY_64B 0x21 +#define CPUID_CACHE_TLB_DESC_L3_512K_4WAY_64B_2LPS 0x22 +#define CPUID_CACHE_TLB_DESC_L3_1M_8WAY_64B_2LPS 0x23 +#define CPUID_CACHE_TLB_DESC_L2_1M_16WAY_64B 0x24 +#define CPUID_CACHE_TLB_DESC_L3_2M_8WAY_64B_2LPS 0x25 +#define CPUID_CACHE_TLB_DESC_L3_4M_8WAY_64B_2LPS 0x29 +#define CPUID_CACHE_TLB_DESC_L1_DATA_32K_8WAY_64B 0x2C +#define CPUID_CACHE_TLB_DESC_L1_INST_32K_8WAY_64B 0x30 +#define CPUID_CACHE_TLB_DESC_NO_L2_OR_L3 0x40 +#define CPUID_CACHE_TLB_DESC_L2_128K_4WAY_32B 0x41 +#define CPUID_CACHE_TLB_DESC_L2_256K_4WAY_32B 0x42 +#define CPUID_CACHE_TLB_DESC_L2_512K_4WAY_32B 0x43 +#define CPUID_CACHE_TLB_DESC_L2_1M_4WAY_32B 0x44 +#define CPUID_CACHE_TLB_DESC_L2_2M_4WAY_32B 0x45 +#define CPUID_CACHE_TLB_DESC_L3_4M_4WAY_64B 0x46 +#define CPUID_CACHE_TLB_DESC_L3_8M_8WAY_64B 0x47 +#define CPUID_CACHE_TLB_DESC_L2_3M_12WAY_64B 0x48 +#define CPUID_CACHE_TLB_DESC_L3_4M_16WAY_64B 0x49 +#define CPUID_CACHE_TLB_DESC_L3_6M_12WAY_64B 0x4A +#define CPUID_CACHE_TLB_DESC_L3_8M_16WAY_64B 0x4B +#define CPUID_CACHE_TLB_DESC_L3_12M_12WAY_64B 0x4C +#define CPUID_CACHE_TLB_DESC_L3_16M_16WAY_64B 0x4D +#define CPUID_CACHE_TLB_DESC_L2_6M_24WAY_64B 0x4E +#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_32E 0x4F +#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_2M_4M_64E 0x50 +#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_2M_4M_128E 0x51 +#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_2M_4M_256E 0x52 +#define CPUID_CACHE_TLB_DESC_TLB_INST_2M_4M_FULLY_7E 0x55 +#define CPUID_CACHE_TLB_DESC_DTLB0_4M_4WAY_16E 0x56 +#define CPUID_CACHE_TLB_DESC_DTLB0_4K_4WAY_16E 0x57 +#define CPUID_CACHE_TLB_DESC_DTLB0_4K_FULLY_16E 0x59 +#define CPUID_CACHE_TLB_DESC_DTLB0_2M_4M_4WAY_32E 0x5A +#define CPUID_CACHE_TLB_DESC_DTLB_4K_4M_64E 0x5B +#define CPUID_CACHE_TLB_DESC_DTLB_4K_4M_128E 0x5C +#define CPUID_CACHE_TLB_DESC_DTLB_4K_4M_256E 0x5D +#define CPUID_CACHE_TLB_DESC_L1_DATA_16K_8WAY_64B 0x60 +#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_FULLY_48E 0x61 +#define CPUID_CACHE_TLB_DESC_DTLB_2M_4M_32E_1G_4WAY_4E 0x63 +#define CPUID_CACHE_TLB_DESC_DTLB_4K_4WAY_512E 0x64 +#define CPUID_CACHE_TLB_DESC_L1_DATA_8K_4WAY_64B 0x66 +#define CPUID_CACHE_TLB_DESC_L1_DATA_16K_4WAY_64B_DUPLICATE 0x67 //???????????? +#define CPUID_CACHE_TLB_DESC_L1_DATA_32K_4WAY_64B 0x68 +#define CPUID_CACHE_TLB_DESC_UTLB_4K_8WAY_64E 0x6A +#define CPUID_CACHE_TLB_DESC_DTLB_4K_8WAY_256E 0x6B +#define CPUID_CACHE_TLB_DESC_DTLB_2M_4M_8WAY_128E 0x6C +#define CPUID_CACHE_TLB_DESC_DTLB_1G_FULLY_16E 0x6D +#define CPUID_CACHE_TLB_DESC_TRACE_12K_8WAY 0x70 +#define CPUID_CACHE_TLB_DESC_TRACE_16K_8WAY 0x71 +#define CPUID_CACHE_TLB_DESC_TRACE_32K_8WAY 0x72 +#define CPUID_CACHE_TLB_DESC_TLB_INST_2M_4M_FULLY_8E 0x76 +#define CPUID_CACHE_TLB_DESC_L2_1M_4WAY_64B 0x78 +#define CPUID_CACHE_TLB_DESC_L2_128K_8WAY_64B_2LPS 0x79 +#define CPUID_CACHE_TLB_DESC_L2_256K_8WAY_64B_2LPS 0x7A +#define CPUID_CACHE_TLB_DESC_L2_512K_8WAY_64B_2LPS 0x7B +#define CPUID_CACHE_TLB_DESC_L2_1M_8WAY_64B_2LPS 0x7C +#define CPUID_CACHE_TLB_DESC_L2_2M_8WAY_64B 0x7D +#define CPUID_CACHE_TLB_DESC_L2_512K_2WAY_64B 0x7F +#define CPUID_CACHE_TLB_DESC_L2_512K_8WAY_64B 0x80 +#define CPUID_CACHE_TLB_DESC_L2_256K_8WAY_32B 0x82 +#define CPUID_CACHE_TLB_DESC_L2_512K_8WAY_32B 0x83 +#define CPUID_CACHE_TLB_DESC_L2_1M_8WAY_32B 0x84 +#define CPUID_CACHE_TLB_DESC_L2_2M_8WAY_32B 0x85 +#define CPUID_CACHE_TLB_DESC_L2_512K_4WAY_64B 0x86 +#define CPUID_CACHE_TLB_DESC_L2_1M_8WAY_64B 0x87 +#define CPUID_CACHE_TLB_DESC_DTLB_4K_FULLY_ASSOC_32E 0xA0 +#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_4WAY_128E 0xB0 +#define CPUID_CACHE_TLB_DESC_TLB_INST_2M_4WAY_8E_4M_4WAY_4E 0xB1 +#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_4WAY_64E 0xB2 +#define CPUID_CACHE_TLB_DESC_TLB_DATA_4K_4WAY_128E 0xB3 +#define CPUID_CACHE_TLB_DESC_TLB_DATA_4K_4WAY_256E 0xB4 +#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_8WAY_64E 0xB5 +#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_8WAY_128E 0xB6 +#define CPUID_CACHE_TLB_DESC_TLB_DATA_4K_4WAY_64E 0xBA +#define CPUID_CACHE_TLB_DESC_TLB_DATA_4K_4M_4WAY_8E 0xC0 +#define CPUID_CACHE_TLB_DESC_STLB_2ND_LEVEL_4K_2M_8WAY_1024E 0xC1 +#define CPUID_CACHE_TLB_DESC_DTLB_4K_2M_4WAY_16E 0xC2 +#define CPUID_CACHE_TLB_DESC_STLB_2ND_LEVEL_4K_2M_6WAY_1536E_1GB_4WAY_16E 0xC3 +#define CPUID_CACHE_TLB_DESC_DTLB_2M_4M_4WAY_32E 0xC4 +#define CPUID_CACHE_TLB_DESC_STLB_2ND_LEVEL_4K_4WAY_512E 0xCA +#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_512KB_4WAY_64B_LINE 0xD0 +#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_1MB_4WAY_64B_LINE 0xD1 +#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_2MB_4WAY_64B_LINE 0xD2 +#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_1MB_8WAY_64B_LINE 0xD6 +#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_2MB_8WAY_64B_LINE 0xD7 +#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_4MB_8WAY_64B_LINE 0xD8 +#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_1_5MB_12WAY_64B_LINE 0xDC +#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_3MB_12WAY_64B_LINE 0xDD +#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_6MB_12WAY_64B_LINE 0xDE +#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_2MB_16WAY_64B_LINE 0xE2 +#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_4MB_16WAY_64B_LINE 0xE3 +#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_8MB_16WAY_64B_LINE 0xE4 +#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_12MB_24WAY_64B_LINE 0xEA +#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_18MB_24WAY_64B_LINE 0xEB +#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_24MB_24WAY_64B_LINE 0xEC +#define CPUID_CACHE_TLB_DESC_PREFETCH_64_BYTE 0xF0 +#define CPUID_CACHE_TLB_DESC_PREFETCH_128_BYTE 0xF1 +#define CPUID_CACHE_TLB_DESC_NO_TLB_INFO_CPUID_LEAF_18H 0xFE +#define CPUID_CACHE_TLB_DESC_NO_CACHE_INFO_CPUID_LEAF_4 0xFF + +//=============CPUID_SERIAL_NUMBER============= +#define CPUID_SERIAL_NUMBER_STITCH(ECX,EDX) (uint64_t)((EDX << 32) | ECX) + +//=============CPUID_CACHE_PARAMS============== +#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE 0xF +#define CPUID_CACHE_PARAMS_EAX_CACHE_LEVEL 0x7 << 4 +#define CPUID_CACHE_PARAMS_EAX_IS_SELF_INIT 1 << 8 +#define CPUID_CACHE_PARAMS_EAX_IS_FULLY_ASSOCIATIVE 1 << 9 +// bits 10-13 are reserved +#define CPUID_CACHE_PARAMS_EAX_MAX_PROC_SHARING 0xFFF << 14 + +#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE_NULL 0x0 +#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE_DATA 0x1 +#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE_INSTRUCTION 0x2 +#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE_UNIFIED 0x3 + +#define CPUID_CACHE_PARAMS_EBX_COHERENCY_LINE_SIZE 0xFFF +#define CPUID_CACHE_PARAMS_EBX_PHYS_LINE_PARTITIONS 0x3FF << 12 +#define CPUID_CACHE_PARAMS_EBX_WAYS_OF_ASSOCIVITY 0x3FF + +#define CPUID_CACHE_PARAMS_EDX_CACHE_INCLUSIVENESS 1 +#define CPUID_CACHE_PARAMS_EDX_COMPLEX_CACHE_INDEXING 1 << 1 + +//=============CPUID_MONITOR_MWAIT============= +#define CPUID_MONITOR_MWAIT_ECX_ENUM_EXTENSIONS 1 +#define CPUID_MONITOR_MWAIT_ECX_BREAK_EVENTS 1 << 1 + +#define CPUID_MONITOR_MWAIT_EDX_C0_SUBC_STATES 0xF +#define CPUID_MONITOR_MWAIT_EDX_C1_SUBC_STATES 0xF << 4 +#define CPUID_MONITOR_MWAIT_EDX_C2_SUBC_STATES 0xF << 8 +#define CPUID_MONITOR_MWAIT_EDX_C3_SUBC_STATES 0xF << 12 +#define CPUID_MONITOR_MWAIT_EDX_C4_SUBC_STATES 0xF << 16 +#define CPUID_MONITOR_MWAIT_EDX_C5_SUBC_STATES 0xF << 20 +#define CPUID_MONITOR_MWAIT_EDX_C6_SUBC_STATES 0xF << 24 +#define CPUID_MONITOR_MWAIT_EDX_C7_SUBC_STATES 0xF << 28 + +//===========CPUID_THERMAL_AND_POWER=========== +#define CPUID_THERMAL_AND_POWER_EAX_TEMP_SENSOR 1 +#define CPUID_THERMAL_AND_POWER_EAX_TURBO_BOOST 1 << 1 +#define CPUID_THERMAL_AND_POWER_EAX_ARAT 1 << 2 +//Bit 3 is reserved +#define CPUID_THERMAL_AND_POWER_EAX_PLN 1 << 3 +#define CPUID_THERMAL_AND_POWER_EAX_ECMD 1 << 5 +#define CPUID_THERMAL_AND_POWER_EAX_PTM 1 << 6 +#define CPUID_THERMAL_AND_POWER_EAX_HWP 1 << 7 +#define CPUID_THERMAL_AND_POWER_EAX_HWP_NOTIFICATION 1 << 8 +#define CPUID_THERMAL_AND_POWER_EAX_HWP_ACT_WINDOW 1 << 9 +#define CPUID_THERMAL_AND_POWER_EAX_HWP_PERF_PREF 1 << 10 +#define CPUID_THERMAL_AND_POWER_EAX_HWP_PKG_LVL_REQ 1 << 11 +//Bit 12 is reserved +#define CPUID_THERMAL_AND_POWER_EAX_HDC 1 << 13 +#define CPUID_THERMAL_AND_POWER_EAX_TURBO_BOOST_MAX 1 << 14 +#define CPUID_THERMAL_AND_POWER_EAX_HWP_CAPABILITIES 1 << 15 +#define CPUID_THERMAL_AND_POWER_EAX_HWP_PECI 1 << 16 +#define CPUID_THERMAL_AND_POWER_EAX_FLEXIBLE_HWP 1 << 17 +#define CPUID_THERMAL_AND_POWER_EAX_FAST_HWP_REQUEST 1 << 18 +#define CPUID_THERMAL_AND_POWER_EAX_HW_FEEDBACK 1 << 19 +#define CPUID_THERMAL_AND_POWER_EAX_IGNORE_HWP_IDLE 1 << 20 +//Bits 21 and 22 are reserved +#define CPUID_THERMAL_AND_POWER_EAX_THREAD_DIRECTOR 1 << 23 +#define CPUID_THERMAL_AND_POWER_EAX_THERM_INTERRUPT 1 << 24 + +#define CPUID_THERMAL_AND_POWER_EBX_INT_TRESHOLD 0xf + +#define CPUID_THERMAL_AND_POWER_ECX_HW_COORD_FEEDBACK 1 +#define CPUID_THERMAL_AND_POWER_ECX_ENERGY_PERF_BIAS 1 << 3 +#define CPUID_THERMAL_AND_POWER_ECX_TD_CLASSES 0xff << 8 + +#define CPUID_THERMAL_AND_POWER_EDX_PERF_REPORT 1 +#define CPUID_THERMAL_AND_POWER_EDX_EFFICIENCY_REPORT 1 << 1 +#define CPUID_THERMAL_AND_POWER_EDX_HW_FEEDBACK_SIZE 0xf << 8 +#define CPUID_THERMAL_AND_POWER_EDX_THIS_PROC_HW_FB 0xffff << 16 + +//===========CPUID_EXTENDED_FEATURES=========== +#define CPUID_EXTENDED_FEATURES_EBX_FSGSBASE 1 +#define CPUID_EXTENDED_FEATURES_EBX_TSC_ADJUST 1 << 1 +#define CPUID_EXTENDED_FEATURES_EBX_SGX 1 << 2 +#define CPUID_EXTENDED_FEATURES_EBX_BMI1 1 << 3 +#define CPUID_EXTENDED_FEATURES_EBX_HLE 1 << 4 +#define CPUID_EXTENDED_FEATURES_EBX_AVX2 1 << 5 +#define CPUID_EXTENDED_FEATURES_EBX_FDP_EXCPTN_ONLY 1 << 6 +#define CPUID_EXTENDED_FEATURES_EBX_SMEP 1 << 7 +#define CPUID_EXTENDED_FEATURES_EBX_BMI2 1 << 8 +#define CPUID_EXTENDED_FEATURES_EBX_ENHANCED_REP 1 << 9 +#define CPUID_EXTENDED_FEATURES_EBX_INVCIP 1 << 10 +#define CPUID_EXTENDED_FEATURES_EBX_RTM 1 << 11 +#define CPUID_EXTENDED_FEATURES_EBX_RDT_M 1 << 12 +#define CPUID_EXTENDED_FEATURES_EBX_NO_FPU_CS 1 << 13 +#define CPUID_EXTENDED_FEATURES_EBX_MPX 1 << 14 +#define CPUID_EXTENDED_FEATURES_EBX_RDT_A 1 << 15 +#define CPUID_EXTENDED_FEATURES_EBX_AVX512F 1 << 16 +#define CPUID_EXTENDED_FEATURES_EBX_AVX512DQ 1 << 17 +#define CPUID_EXTENDED_FEATURES_EBX_RDSEED 1 << 18 +#define CPUID_EXTENDED_FEATURES_EBX_ADX 1 << 19 +#define CPUID_EXTENDED_FEATURES_EBX_SMAP 1 << 20 +#define CPUID_EXTENDED_FEATURES_EBX_AVX512_IFMA 1 << 21 +// Bit 22 is reserved +#define CPUID_EXTENDED_FEATURES_EBX_CLFLUSHOPT 1 << 23 +#define CPUID_EXTENDED_FEATURES_EBX_CLWB 1 << 24 +#define CPUID_EXTENDED_FEATURES_EBX_TRACE 1 << 25 +#define CPUID_EXTENDED_FEATURES_EBX_AVX512PF 1 << 26 +#define CPUID_EXTENDED_FEATURES_EBX_AVX512ER 1 << 27 +#define CPUID_EXTENDED_FEATURES_EBX_AVX512CD 1 << 28 +#define CPUID_EXTENDED_FEATURES_EBX_SHA 1 << 29 +#define CPUID_EXTENDED_FEATURES_EBX_AVX512BW 1 << 30 +#define CPUID_EXTENDED_FEATURES_EBX_AVX512VL 1 << 31 + +#define CPUID_EXTENDED_FEATURES_ECX_PREFETCHWT1 1 +#define CPUID_EXTENDED_FEATURES_ECX_AFX512_VBMI 1 << 1 +#define CPUID_EXTENDED_FEATURES_ECX_UMIP 1 << 2 +#define CPUID_EXTENDED_FEATURES_ECX_PKU 1 << 3 +#define CPUID_EXTENDED_FEATURES_ECX_OSPKE 1 << 4 +#define CPUID_EXTENDED_FEATURES_ECX_WAITPKG 1 << 5 +#define CPUID_EXTENDED_FEATURES_ECX_AVX512_VBMI2 1 << 6 +#define CPUID_EXTENDED_FEATURES_ECX_CET_SS 1 << 7 +#define CPUID_EXTENDED_FEATURES_ECX_GFNI 1 << 8 +#define CPUID_EXTENDED_FEATURES_ECX_VAES 1 << 9 +#define CPUID_EXTENDED_FEATURES_ECX_VPCLMULQDQ 1 << 10 +#define CPUID_EXTENDED_FEATURES_ECX_AVX512_VNNI 1 << 11 +#define CPUID_EXTENDED_FEATURES_ECX_AVX512_BITLANG 1 << 12 +#define CPUID_EXTENDED_FEATURES_ECX_TME_EN 1 << 13 +#define CPUID_EXTENDED_FEATURES_ECX_AVX512_VPOPVNZDQ 1 << 14 +//bit 15 is reserved +#define CPUID_EXTENDED_FEATURES_ECX_LA57 1 << 16 +#define CPUID_EXTENDED_FEATURES_ECX_MAWAU_VAL 0x1F << 17 +#define CPUID_EXTENDED_FEATURES_ECX_RDPID 1 << 22 +#define CPUID_EXTENDED_FEATURES_ECX_KL 1 << 23 +#define CPUID_EXTENDED_FEATURES_ECX_BUS_LOCK_DETECT 1 << 24 +#define CPUID_EXTENDED_FEATURES_ECX_CLDEMOTE 1 << 25 +//bit 26 is reserved +#define CPUID_EXTENDED_FEATURES_ECX_MOVDIRI 1 << 27 +#define CPUID_EXTENDED_FEATURES_ECX_MOVDIR64B 1 << 28 +#define CPUID_EXTENDED_FEATURES_ECX_ENQCMD 1 << 29 +#define CPUID_EXTENDED_FEATURES_ECX_SGX_LC 1 << 30 +#define CPUID_EXTENDED_FEATURES_ECX_PKS 1 << 31 + +//bit 0 is reserved +#define CPUID_EXTENDED_FEATURES_EDX_SGX_KEYS 1 << 1 +#define CPUID_EXTENDED_FEATURES_EDX_AVX512_4VNNIW 1 << 2 +#define CPUID_EXTENDED_FEATURES_EDX_AVX512_4FMAPS 1 << 3 +#define CPUID_EXTENDED_FEATURES_EDX_FAST_REP_MOV 1 << 4 +#define CPUID_EXTENDED_FEATURES_EDX_UINTR 1 << 5 +//bits 6 and 7 are reserved +#define CPUID_EXTENDED_FEATURES_EDX_AVX512_VPINTERSECT 1 << 8 // intel you son of a bitch +#define CPUID_EXTENDED_FEATURES_EDX_SRBDS_CTRL 1 << 9 +#define CPUID_EXTENDED_FEATURES_EDX_MD_CLEAR 1 << 10 +#define CPUID_EXTENDED_FEATURES_EDX_RTM_ALWAYS_ABORT 1 << 11 +//bit 12 is reserved +#define CPUID_EXTENDED_FEATURES_EDX_RTM_FORCE_ABORT 1 << 13 +#define CPUID_EXTENDED_FEATURES_EDX_SERIALIZE 1 << 14 +#define CPUID_EXTENDED_FEATURES_EDX_HYBRID 1 << 15 +#define CPUID_EXTENDED_FEATURES_EDX_TSXLDTRK 1 << 16 +//bit 17 is reserved +#define CPUID_EXTENDED_FEATURES_EDX_PCONFIG 1 << 18 +#define CPUID_EXTENDED_FEATURES_EDX_ARCHITECTURAL_LBR 1 << 19 +#define CPUID_EXTENDED_FEATURES_EDX_CET_IBT 1 << 20 +//bit 21 is reserved +#define CPUID_EXTENDED_FEATURES_EDX_AMX_BF16 1 << 22 +#define CPUID_EXTENDED_FEATURES_EDX_AVX512_FP16 1 << 23 +#define CPUID_EXTENDED_FEATURES_EDX_AMX_TILE 1 << 24 +#define CPUID_EXTENDED_FEATURES_EDX_AMX_INT8 1 << 25 +#define CPUID_EXTENDED_FEATURES_EDX_IBRS 1 << 26 +#define CPUID_EXTENDED_FEATURES_EDX_STIBP 1 << 27 +#define CPUID_EXTENDED_FEATURES_EDX_L1D_FLUSH 1 << 28 +#define CPUID_EXTENDED_FEATURES_EDX_ARCH_CAPABS_MSR 1 << 29 +#define CPUID_EXTENDED_FEATURES_EDX_CORE_CAPABS_MSR 1 << 30 +#define CPUID_EXTENDED_FEATURES_EDX_SSBD 1 << 31 + +//=========CPUID_EXTENDED_FEATURES_SL1========= +//bits 0-3 are reserved +#define CPUID_EXTENDED_FEATURES_SL1_EAX_AVX_VNNI 1 << 4 +#define CPUID_EXTENDED_FEATURES_SL1_EAX_AVX512_BF16 1 << 5 +//bits 6-9 are reserved +#define CPUID_EXTENDED_FEATURES_SL1_EAX_0_REP_MOVSB 1 << 10 +#define CPUID_EXTENDED_FEATURES_SL1_EAX_FAST_STOSB 1 << 11 +#define CPUID_EXTENDED_FEATURES_SL1_EAX_FAST_CMPSB 1 << 12 +//bits 13-21 are reserved +#define CPUID_EXTENDED_FEATURES_SL1_EAX_HRESET 1 << 22 +//bits 23-19 are reserved +#define CPUID_EXTENDED_FEATURES_SL1_EAX_INVD_POSTPOST 1 << 30 +//bit 31 is reserved + +#define CPUID_EXTENDED_FEATURES_SL1_EBX_PPIN 1 + +#define CPUID_EXTENDED_FEATURES_SL1_EDX_CET_SSS 1 << 18 + +//=========CPUID_EXTENDED_FEATURES_SL2========= +#define CPUID_EXTENDED_FEATURES_SL2_EDX_PSFD 1 +#define CPUID_EXTENDED_FEATURES_SL2_EDX_IPRED_CTRL 1 << 1 +#define CPUID_EXTENDED_FEATURES_SL2_EDX_RRSBA_CTRL 1 << 2 +#define CPUID_EXTENDED_FEATURES_SL2_EDX_DDPD_U 1 << 3 +#define CPUID_EXTENDED_FEATURES_SL2_EDX_BHI_CTRL 1 << 4 +//The rest of the bits are reserved + + +enum leaves { + /* @ Basic CPU info + * @ Returned EAX: Highest basic CPUID leaf present + * @ Returned EBX: First 4 letters of the vendor identifier string + * @ Returned ECX: Third 4 letters of the vendor identifier string + * @ Retruned EDX: Second 4 letters of the vendor identifier string + */ + CPUID_VENDOR = 0x00000000, + /* @ CPU Version information + * @ Returned EAX: Family,Model,Stepping + * @ Returned EBX: Brand Index,CLFLUSH line size, Max number of logical processors + * @ Returned ECX: Featrue information + * @ Retruned EDX: More feature information + */ + CPUID_CPU_INFO = 0x00000001, + /* @ CPU Cache and TLB information + * @ Returned EAX: 4 Cache, prefetch or TLB descriptors + * @ Returned EBX: 4 Cache, prefetch or TLB descriptors + * @ Returned ECX: 4 Cache, prefetch or TLB descriptors + * @ Retruned EDX: 4 Cache, prefetch or TLB descriptors + */ + CPUID_CACHE_TLB = 0x00000002, + /* @ CPU Serial Number !!! PENTIUM 3 ONLY !!! + * @ Returned EAX: Reserved + * @ Returned EBX: Reserved + * @ Returned ECX: bits 0-31 of the serial number + * @ Retruned EDX: bits 32-63 of the serial number + */ + CPUID_SERIAL_NUMBER = 0x00000003, + /* @ CPU Deterministic cache parameters !!! Initial ECX = Cache level !!! + * @ Returned EAX: Cache level,Is self init,Is fully associative,Maximum number of addressable IDs for logical processors sharing this cache + * @ Returned EBX: L, P and W + * @ Returned ECX: S + * @ Retruned EDX: Cache inclusiveness and Complex Cache indexing + */ + CPUID_CACHE_PARAMS = 0x00000004, + /* @ MONITOR/MWAIT params + * @ Returned EAX: Smallest monitor-line size + * @ Returned EBX: Largest monitor-line size + * @ Returned ECX: Enumeration of Monitor-Mwait extensions,Supports treating interrupts as break-event for MWAIT + * @ Retruned EDX: Number of sub C-states supported using MWAIT for each C number thingy IDK + */ + CPUID_MONITOR_MWAIT = 0x00000005, + /* @ Thermal and power managment + * @ Returned EAX: Thermal and power info + * @ Returned EBX: Thermal and power info + * @ Returned ECX: Thermal and power info + * @ Retruned EDX: Thermal and power info + */ + CPUID_THERMAL_AND_POWER = 0x00000006, + /* @ Extended features + * @ Returned EAX: Number of subleaves supported + * @ Returned EBX: Features + * @ Returned ECX: Features + * @ Retruned EDX: Features + */ + CPUID_EXTENDED_FEATURES = 0x00000007, + /* @ Direct Cache Access Information + * @ Returned EAX: Value of the MSR "IA32_PLATFORM_DCA_CAP" + * @ Returned EBX: Reserved + * @ Returned ECX: Reserved + * @ Retruned EDX: Reserved + */ + CPUID_CACHE_ACCESS_INFO = 0x00000009, + CPUID_PERFORMANCE_MONITORING = 0x0000000A, + CPUID_EXTENDENDED_TOPOLOGY = 0x0000000B, + CPUID_EXTENDENDED_TOPOLOGY2 = 0x0000000D, + CPUID_INTEL_RDT = 0x0000000F, + CPUID_INTEL_RDT2 = 0x00000010, + CPUID_INTEL_SGX = 0x00000012, + CPUID_CPU_TRACE_ENUM = 0x00000014, + CPUID_TSC = 0x00000015, + CPUID_CPU_FREQ_INFO = 0x00000016, + CPUID_SOC_VENDOR = 0x00000017, + CPUID_DETERMINISTIC_ADRESS_TRANSLATION_PARAMS = 0x00000018, + CPUID_KEY_LOCKER = 0x000000019, + CPUID_NATIVE_MODEL_ID = 0x0000001A, + CPUID_PCONFIG_INFO = 0x0000001B, + CPUID_LAST_BRACH = 0x00000001C, + CPUID_TILE_INFO = 0x00000001D, + CPUID_TMUL_INFO = 0x00000001E, + CPUID_V2_EXTENDED_TOPOLOGY = 0x00000001F, + CPUID_V2_EXTENDED_TOPOLOGY2 = 0x000000020, + //TODO: add the bitmasks for these Microsoft ones + /* @ Hypervisor CPUID Leaf Range + * @ Returned EAX: Highest hypervisor CPUID leaf present + * @ Returned EBX: Largest monitor-line size + * @ Returned ECX: Enumeration of Monitor-Mwait extensions,Supports treating interrupts as break-event for MWAIT + * @ Retruned EDX: Number of sub C-states supported using MWAIT for each C number thingy IDK + */ + CPUID_HYPERV_IDENT = 0x40000000, + /* @ Hypervisor Vendor-Neutral Interface Identification + * @ Returned EAX: Hypervisor interface signature + * @ Returned EBX: Reserved + * @ Returned ECX: Reserved + * @ Retruned EDX: Reserved + */ + CPUID_MS_HYPERV_INTERFCE_IDENT = 0x40000001, + /* @ Hypervisor System Identity + * @ Returned EAX: Build number + * @ Returned EBX: Major and minor version + * @ Returned ECX: Reserved + * @ Retruned EDX: Reserved + */ + CPUID_MS_HYPERV_SYSTEM_IDENT = 0x40000002, + /* @ Hypervisor Feature Identification + * @ Returned EAX: bits 0-31 of HV_PARTITION_PRIVILEGE_MASK + * @ Returned EBX: bits 31-63 of HV_PARTITION_PRIVILEGE_MASK + * @ Returned ECX: Hyper-V features + * @ Retruned EDX: Hyper-V features + */ + CPUID_MS_HYPERV_FEATURE_IDENT = 0x40000003, + /* @ Implementation Recommendations + * @ Returned EAX: Hyper-V feature recommendations + * @ Returned EBX: Hyper-V feature recommendations + * @ Returned ECX: Hyper-V feature recommendations + * @ Retruned EDX: Reserved + */ + CPUID_MS_HYPERV_RECOMMENDATIONS = 0x40000004, + /* @ Hypervisor Implementation Limits + * @ Returned EAX: The maximum number of virtual processors supported + * @ Returned EBX: The maximum number of logical processors supported + * @ Returned ECX: The maximum number of physical interrupt vectors available for interrupt remapping. + * @ Retruned EDX: Reserved + */ + CPUID_MS_HYPERV_IMPL_LIMITS = 0x40000005, + /* @ Implementation Hardware Features + * @ Returned EAX: Hardware features + * @ Returned EBX: Reserved + * @ Returned ECX: Reserved + * @ Retruned EDX: Reserved + */ + CPUID_MS_HYPERV_HARDWARE_FEATURES = 0x40000006, + /* @ Nested Hypervisor Feature Identification + * @ Returned EAX: Nested Hypervisor features + * @ Returned EBX: Reserved + * @ Returned ECX: Reserved + * @ Retruned EDX: Nested Hypervisor features + */ + CPUID_MS_HYPERV_NESTED_FEATURES = 0x40000009, + /* @ Nested Hypervisor Nested Virtualization Features + * @ Returned EAX: Nested Hypervisor features + * @ Returned EBX: Nested Hypervisor features + * @ Returned ECX: Reserved + * @ Retruned EDX: Reserved + */ + CPUID_MS_HYPERV_NESTED_OPTIMISATIONS = 0x4000000A, + /* @ Extended processor signature + * @ Returned EAX: Reserved + * @ Returned EBX: Reserved + * @ Returned ECX: Extended feature bits + * @ Retruned EDX: Extended feature bits + */ + CPUID_EXTENDED_SIGNATURE = 0x800000001, + /* @ Full CPU name + * @ Returned EAX: First 4 characters of the full CPU name + * @ Returned EBX: Second 4 characters of the full CPU name + * @ Returned ECX: Third 4 characters of the full CPU name + * @ Retruned EDX: Fourth 4 characters of the full CPU name + */ + CPUID_BRAND_STRING1 = 0x800000002, + /* @ Full CPU name 2 + * @ Returned EAX: Fifth 4 characters of the full CPU name + * @ Returned EBX: Sexth 4 characters of the full CPU name + * @ Returned ECX: Seventh 4 characters of the full CPU name + * @ Retruned EDX: Eightth 4 characters of the full CPU name + */ + CPUID_BRAND_STRING2 = 0x800000003, + /* @ Full CPU name 3 + * @ Returned EAX: Nineth 4 characters of the full CPU name + * @ Returned EBX: Tenth 4 characters of the full CPU name + * @ Returned ECX: Eleventh 4 characters of the full CPU name + * @ Retruned EDX: Twelveth 4 characters of the full CPU name + */ + CPUID_BRAND_STRING3 = 0x800000004, + /* @ Cache line size and associativity + * @ Returned EAX: Reserved + * @ Returned EBX: Reserved + * @ Returned ECX: Bits 0-7 = Cache line size in bytes, Bits 12-15 = L2 Associativity, Bits 16-31 = Cache size in 1K blocks + * @ Retruned EDX: Reserved + */ + CPUID_MORE_CACHE = 0x800000006, + /* @ Invariant TSC available + * @ Returned EAX: Reserved + * @ Returned EBX: Reserved + * @ Returned ECX: Bit 8 = Invariant TSC available + * @ Retruned EDX: Reserved + */ + CPUID_INVARIANT_TSC_AVAILABLE = 0x800000007, + /* @ Physical adress size + * @ Returned EAX: Bits 0-7 = Physical Adress bits, Bits 8-15 = Linear Address bits + * @ Returned EBX: Bit 9 = WBNOINVD available + * @ Returned ECX: Reserved + * @ Retruned EDX: Reserved + */ + CPUID_PHYS_ADDR_SIZE = 0x800000008, +}; + +enum sub_leaves{ + /* @ Extended features available subleaf 1 !!! All fields return 0 is info not available !!! + * @ Returned EAX: Features + * @ Returned EBX: PPIN + * @ Returned ECX: Reserved + * @ Retruned EDX: CET_SSS + */ + CPUID_EXTENDED_FEATURES_SL1 = 0x00000001, + /* @ Extended features available subleaf 2 !!! All fields return 0 is info not available !!! + * @ Returned EAX: Reserved + * @ Returned EBX: Reserved + * @ Returned ECX: Reserved + * @ Retruned EDX: Features + */ + CPUID_EXTENDED_FEATURES_SL2 = 0x00000002, + CPUID_INTEL_RDT_CAPABILITY = 0x00000001, + CPUID_INTEL_RDT2_ALLOCATION = 0x00000000, + CPUID_INTEL_RDT2_RESID1 = 0x00000001, + CPUID_INTEL_RDT2_RESID2 = 0x00000002, + CPUID_INTEL_RDT2_RESID3 = 0x00000003, + CPUID_INTEL_SGX_SL1 = 0x00000001, + CPUID_INTEL_SGX_SL2 = 0x00000002, + CPUID_CPU_TRACE_ENUM_SL = 0x00000001, + CPUID_SOC_VENDOR_SL1 = 0x00000001, + CPUID_SOC_VENDOR_SL2 = 0x00000002, + CPUID_SOC_VENDOR_SL3 = 0x00000003, + //NOTE: goes higher than 1 + CPUID_DETERMINISTIC_ADRESS_TRANSLATION_PARAMS_SL = 0x00000001, + CPUID_TILE_INFO_PALETTE1 = 0x000000001, +}; + +static inline void cpuid(int leaf, int subleaf, int* a, int* b, int* c, int* d) { + __asm__ __volatile__ ( + "cpuid" + : "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d) + : "a" (leaf), "c" (subleaf) + ); +} + +#endif // __CPUID_H__ \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/gdt.c b/kernel/src/sys/arch/x86_64/gdt.c new file mode 100755 index 0000000..0559625 --- /dev/null +++ b/kernel/src/sys/arch/x86_64/gdt.c @@ -0,0 +1,53 @@ +//#include "sys/log.h" +#include +#include +#include + +gdt_table def_table = { + { + 0x0000000000000000, // 0x00 + + 0x00009a000000ffff, // 0x08 16 bit code + 0x000093000000ffff, // 0x10 16 bit data + + 0x00cf9a000000ffff, // 0x18 32 bit code + 0x00cf93000000ffff, // 0x20 32 bit data + + 0x00af9b000000ffff, // 0x28 64 bit code cs + 0x00af93000000ffff, // 0x30 64 bit data ss + + 0x00aff3000000ffff, // 0x38 data ss + 0x00affb000000ffff, // 0x40 user mode code cs + }, + { + } +}; + +tssr tss_list[256]; // One tssr per CPU + +void gdt_init() { + + // TODO: adapt for multiprocessor kernel + tss_list[0].iopb = sizeof(tssr); + uintptr_t tss = (uintptr_t)&tss_list[0]; + + def_table.tss_entry.length = sizeof(tss_entry); + def_table.tss_entry.base = (uint16_t)(tss & 0xffff); + def_table.tss_entry.base1 = (uint8_t)((tss >> 16) & 0xff); + def_table.tss_entry.flags = 0x89; + def_table.tss_entry.flags1 = 0; + def_table.tss_entry.base2 = (uint8_t)((tss >> 24) & 0xff); + def_table.tss_entry.base3 = (uint32_t)(tss >> 32); + def_table.tss_entry.resv = 0; + + gdtr gdt = (gdtr){ + .size = (sizeof(gdt_table)) - 1, + .address = (uint64_t)&def_table + }; + + __asm__ volatile ("lgdt %0\n\t" : : "m"(gdt) : "memory"); + __asm__ volatile ("ltr %0\n\t" : : "r"((uint16_t)0x48)); + + //logln(progress, "kinit stage 1", "GDT initialized\n"); + log("gdt - initialized.\n"); +} \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/gdt.h b/kernel/src/sys/arch/x86_64/gdt.h new file mode 100755 index 0000000..8e51e53 --- /dev/null +++ b/kernel/src/sys/arch/x86_64/gdt.h @@ -0,0 +1,37 @@ +#pragma once + +#include + +typedef struct { + uint16_t length; + uint16_t base; + uint8_t base1; + uint8_t flags; + uint8_t flags1; + uint8_t base2; + uint32_t base3; + uint32_t resv; +} __attribute__((packed)) tss_entry; + +typedef struct { + uint64_t gdt_entries[9]; + tss_entry tss_entry; +} __attribute__((packed)) gdt_table; + +typedef struct { + uint16_t size; + uint64_t address; +} __attribute__((packed)) gdtr; + + +typedef struct { + uint32_t resv; + uint64_t rsp[3]; + uint64_t resv1; + uint64_t ist[7]; + uint64_t resv2; + uint16_t resv3; + uint16_t iopb; +} __attribute__((packed)) tssr; // Per CPU + +void gdt_init(); \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/idt.c b/kernel/src/sys/arch/x86_64/idt.c new file mode 100755 index 0000000..37b058a --- /dev/null +++ b/kernel/src/sys/arch/x86_64/idt.c @@ -0,0 +1,44 @@ +//#include "sys/log.h" +#include "sys/arch/x86_64/pic.h" +#include +#include + +__attribute__((aligned(0x10))) +static idt_entry_t idt[256]; + +static idtr_t idtr; + +void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags) { + idt_entry_t* descriptor = &idt[vector]; + + descriptor->isr_low = (uint64_t)isr & 0xFFFF; + descriptor->kernel_cs = 0x28; + descriptor->ist = 0; + descriptor->attributes = flags; + descriptor->isr_mid = ((uint64_t)isr >> 16) & 0xFFFF; + descriptor->isr_high = ((uint64_t)isr >> 32) & 0xFFFFFFFF; + descriptor->reserved = 0; +} + +static int vectors[256]; + +extern void* isr_stub_table[]; + +void idt_init() { + idtr.base = (uintptr_t)&idt[0]; + idtr.limit = (uint16_t)sizeof(idt_entry_t) * 256 - 1; + + for (uint16_t vector = 0; vector <= 256; vector++) { + idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); + vectors[vector] = 1; + } + + pic_init(); + pic_unmask_irq(1); + + __asm__ volatile ("lidt %0" : : "m"(idtr)); // load the new IDT + __asm__ volatile ("sti"); // set the interrupt flag + + //logln(progress, "kinit stage 1", "IDT initialized! Time to receive interrupts!\n"); + log("idt - initialized\n"); +} \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/idt.h b/kernel/src/sys/arch/x86_64/idt.h new file mode 100755 index 0000000..8416f5e --- /dev/null +++ b/kernel/src/sys/arch/x86_64/idt.h @@ -0,0 +1,51 @@ +#pragma once + +#include + +typedef struct { + uint64_t r15; + uint64_t r14; + uint64_t r13; + uint64_t r12; + uint64_t r11; + uint64_t r10; + uint64_t r9; + uint64_t r8; + uint64_t rdi; + uint64_t rsi; + uint64_t rbp; + uint64_t rbx; + uint64_t rdx; + uint64_t rcx; + uint64_t rax; + uint64_t int_no; + uint64_t err_code; + uint64_t rip; + uint64_t cs; + uint64_t rflags; + uint64_t rsp; + uint64_t ss; +} __attribute__((packed)) registers_t; + +typedef struct stackframe { + struct stackframe* rbp; + uint64_t rip; +} stackframe_t; + +typedef struct { + uint16_t isr_low; // The lower 16 bits of the ISR's address + uint16_t kernel_cs; // The GDT segment selector that the CPU will load into CS before calling the ISR + uint8_t ist; // The IST in the TSS that the CPU will load into RSP; set to zero for now + uint8_t attributes; // Type and attributes; see the IDT page + uint16_t isr_mid; // The higher 16 bits of the lower 32 bits of the ISR's address + uint32_t isr_high; // The higher 32 bits of the ISR's address + uint32_t reserved; // Set to zero +} __attribute__((packed)) idt_entry_t; + +typedef struct { + uint16_t limit; + uint64_t base; +} __attribute__((packed)) idtr_t; + +void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags); +void idt_init(void); \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/interrupts.asm b/kernel/src/sys/arch/x86_64/interrupts.asm new file mode 100755 index 0000000..860dc37 --- /dev/null +++ b/kernel/src/sys/arch/x86_64/interrupts.asm @@ -0,0 +1,335 @@ +%macro pushall 0 + push rax + push rcx + push rdx + push rbx + push rbp + push rsi + push rdi + push r8 + push r9 + push r10 + push r11 + push r12 + push r13 + push r14 + push r15 +%endmacro + +%macro popall 0 + pop r15 + pop r14 + pop r13 + pop r12 + pop r11 + pop r10 + pop r9 + pop r8 + pop rdi + pop rsi + pop rbp + pop rbx + pop rdx + pop rcx + pop rax +%endmacro + +%macro isr_err_stub 1 +isr_stub_%+%1: + + push %1 + pushall + + mov rdi, rsp + + call exception_handler + + popall + + add rsp, 16 + iretq +%endmacro + +%macro isr_no_err_stub 1 +isr_stub_%+%1: + push 0 + push %1 + pushall + + mov rdi, rsp + + call exception_handler + + popall + + add rsp, 16 + iretq +%endmacro + +extern exception_handler +isr_no_err_stub 0 +isr_no_err_stub 1 +isr_no_err_stub 2 +isr_no_err_stub 3 +isr_no_err_stub 4 +isr_no_err_stub 5 +isr_no_err_stub 6 +isr_no_err_stub 7 +isr_err_stub 8 +isr_no_err_stub 9 +isr_err_stub 10 +isr_err_stub 11 +isr_err_stub 12 +isr_err_stub 13 +isr_err_stub 14 +isr_no_err_stub 15 +isr_no_err_stub 16 +isr_err_stub 17 +isr_no_err_stub 18 +isr_no_err_stub 19 +isr_no_err_stub 20 +isr_no_err_stub 21 +isr_no_err_stub 22 +isr_no_err_stub 23 +isr_no_err_stub 24 +isr_no_err_stub 25 +isr_no_err_stub 26 +isr_no_err_stub 27 +isr_no_err_stub 28 +isr_no_err_stub 29 +isr_err_stub 30 +isr_no_err_stub 31 + + +isr_no_err_stub 32 +isr_no_err_stub 33 +isr_no_err_stub 34 +isr_no_err_stub 35 +isr_no_err_stub 36 +isr_no_err_stub 37 +isr_no_err_stub 38 +isr_no_err_stub 39 +isr_no_err_stub 40 +isr_no_err_stub 41 +isr_no_err_stub 42 +isr_no_err_stub 43 +isr_no_err_stub 44 +isr_no_err_stub 45 +isr_no_err_stub 46 +isr_no_err_stub 47 +isr_no_err_stub 48 +isr_no_err_stub 49 +isr_no_err_stub 50 +isr_no_err_stub 51 +isr_no_err_stub 52 +isr_no_err_stub 53 +isr_no_err_stub 54 +isr_no_err_stub 55 +isr_no_err_stub 56 +isr_no_err_stub 57 +isr_no_err_stub 58 +isr_no_err_stub 59 +isr_no_err_stub 60 +isr_no_err_stub 61 +isr_no_err_stub 62 +isr_no_err_stub 63 +isr_no_err_stub 64 +isr_no_err_stub 65 +isr_no_err_stub 66 +isr_no_err_stub 67 +isr_no_err_stub 68 +isr_no_err_stub 69 +isr_no_err_stub 70 +isr_no_err_stub 71 +isr_no_err_stub 72 +isr_no_err_stub 73 +isr_no_err_stub 74 +isr_no_err_stub 75 +isr_no_err_stub 76 +isr_no_err_stub 77 +isr_no_err_stub 78 +isr_no_err_stub 79 +isr_no_err_stub 80 +isr_no_err_stub 81 +isr_no_err_stub 82 +isr_no_err_stub 83 +isr_no_err_stub 84 +isr_no_err_stub 85 +isr_no_err_stub 86 +isr_no_err_stub 87 +isr_no_err_stub 88 +isr_no_err_stub 89 +isr_no_err_stub 90 +isr_no_err_stub 91 +isr_no_err_stub 92 +isr_no_err_stub 93 +isr_no_err_stub 94 +isr_no_err_stub 95 +isr_no_err_stub 96 +isr_no_err_stub 97 +isr_no_err_stub 98 +isr_no_err_stub 99 +isr_no_err_stub 100 +isr_no_err_stub 101 +isr_no_err_stub 102 +isr_no_err_stub 103 +isr_no_err_stub 104 +isr_no_err_stub 105 +isr_no_err_stub 106 +isr_no_err_stub 107 +isr_no_err_stub 108 +isr_no_err_stub 109 +isr_no_err_stub 110 +isr_no_err_stub 111 +isr_no_err_stub 112 +isr_no_err_stub 113 +isr_no_err_stub 114 +isr_no_err_stub 115 +isr_no_err_stub 116 +isr_no_err_stub 117 +isr_no_err_stub 118 +isr_no_err_stub 119 +isr_no_err_stub 120 +isr_no_err_stub 121 +isr_no_err_stub 122 +isr_no_err_stub 123 +isr_no_err_stub 124 +isr_no_err_stub 125 +isr_no_err_stub 126 +isr_no_err_stub 127 +isr_no_err_stub 128 +isr_no_err_stub 129 +isr_no_err_stub 130 +isr_no_err_stub 131 +isr_no_err_stub 132 +isr_no_err_stub 133 +isr_no_err_stub 134 +isr_no_err_stub 135 +isr_no_err_stub 136 +isr_no_err_stub 137 +isr_no_err_stub 138 +isr_no_err_stub 139 +isr_no_err_stub 140 +isr_no_err_stub 141 +isr_no_err_stub 142 +isr_no_err_stub 143 +isr_no_err_stub 144 +isr_no_err_stub 145 +isr_no_err_stub 146 +isr_no_err_stub 147 +isr_no_err_stub 148 +isr_no_err_stub 149 +isr_no_err_stub 150 +isr_no_err_stub 151 +isr_no_err_stub 152 +isr_no_err_stub 153 +isr_no_err_stub 154 +isr_no_err_stub 155 +isr_no_err_stub 156 +isr_no_err_stub 157 +isr_no_err_stub 158 +isr_no_err_stub 159 +isr_no_err_stub 160 +isr_no_err_stub 161 +isr_no_err_stub 162 +isr_no_err_stub 163 +isr_no_err_stub 164 +isr_no_err_stub 165 +isr_no_err_stub 166 +isr_no_err_stub 167 +isr_no_err_stub 168 +isr_no_err_stub 169 +isr_no_err_stub 170 +isr_no_err_stub 171 +isr_no_err_stub 172 +isr_no_err_stub 173 +isr_no_err_stub 174 +isr_no_err_stub 175 +isr_no_err_stub 176 +isr_no_err_stub 177 +isr_no_err_stub 178 +isr_no_err_stub 179 +isr_no_err_stub 180 +isr_no_err_stub 181 +isr_no_err_stub 182 +isr_no_err_stub 183 +isr_no_err_stub 184 +isr_no_err_stub 185 +isr_no_err_stub 186 +isr_no_err_stub 187 +isr_no_err_stub 188 +isr_no_err_stub 189 +isr_no_err_stub 190 +isr_no_err_stub 191 +isr_no_err_stub 192 +isr_no_err_stub 193 +isr_no_err_stub 194 +isr_no_err_stub 195 +isr_no_err_stub 196 +isr_no_err_stub 197 +isr_no_err_stub 198 +isr_no_err_stub 199 +isr_no_err_stub 200 +isr_no_err_stub 201 +isr_no_err_stub 202 +isr_no_err_stub 203 +isr_no_err_stub 204 +isr_no_err_stub 205 +isr_no_err_stub 206 +isr_no_err_stub 207 +isr_no_err_stub 208 +isr_no_err_stub 209 +isr_no_err_stub 210 +isr_no_err_stub 211 +isr_no_err_stub 212 +isr_no_err_stub 213 +isr_no_err_stub 214 +isr_no_err_stub 215 +isr_no_err_stub 216 +isr_no_err_stub 217 +isr_no_err_stub 218 +isr_no_err_stub 219 +isr_no_err_stub 220 +isr_no_err_stub 221 +isr_no_err_stub 222 +isr_no_err_stub 223 +isr_no_err_stub 224 +isr_no_err_stub 225 +isr_no_err_stub 226 +isr_no_err_stub 227 +isr_no_err_stub 228 +isr_no_err_stub 229 +isr_no_err_stub 230 +isr_no_err_stub 231 +isr_no_err_stub 232 +isr_no_err_stub 233 +isr_no_err_stub 234 +isr_no_err_stub 235 +isr_no_err_stub 236 +isr_no_err_stub 237 +isr_no_err_stub 238 +isr_no_err_stub 239 +isr_no_err_stub 240 +isr_no_err_stub 241 +isr_no_err_stub 242 +isr_no_err_stub 243 +isr_no_err_stub 244 +isr_no_err_stub 245 +isr_no_err_stub 246 +isr_no_err_stub 247 +isr_no_err_stub 248 +isr_no_err_stub 249 +isr_no_err_stub 250 +isr_no_err_stub 251 +isr_no_err_stub 252 +isr_no_err_stub 253 +isr_no_err_stub 254 +isr_no_err_stub 255 + +global isr_stub_table +isr_stub_table: +%assign i 0 +%rep 256 + dq isr_stub_%+i ; use DQ instead if targeting 64-bit +%assign i i+1 +%endrep \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/interrupts.c b/kernel/src/sys/arch/x86_64/interrupts.c new file mode 100755 index 0000000..d243629 --- /dev/null +++ b/kernel/src/sys/arch/x86_64/interrupts.c @@ -0,0 +1,70 @@ +//#include "mm/pmm.h" +//#include "mm/vmm.h" +#include "mm/vmm.h" +#include "sched/sched.h" +#include "sys/arch/x86_64/pic.h" +#include "sys/arch/x86_64/rtc.h" +#include "sys/log.h" +//#include "sys/sched.h" +#include +#include +#include +//#include + +int pit_millis = 0; +int pit_secs = 0; + +struct Idt_StackFrame { + struct Idt_StackFrame* rbp; + uint64_t rip; +}__attribute__((packed)); + +void dump_backtrace(registers_t *r) +{ + log("ints - backtrace : \n"); + struct Idt_StackFrame* frame = (struct Idt_StackFrame*)r->rbp; + + while (frame) { + log("ints - %s (ip: %p)\n", frame->rip); + frame = frame->rbp; + } + log("ints - \n"); +} + +void pit_handler(registers_t *regs); + +void exception_handler(registers_t *regs) { + vmm_load_pagemap(vmm_kernel_pm); + + if (regs->int_no < 32) { + //panic(kmode_cpu_exception, regs); + log("ints - %d (RIP: %p, ERR: %d)\n", regs->int_no, regs->rip, regs->err_code); + dump_backtrace(regs); + asm ("cli"); + while (1) + asm ("hlt"); + } + + if (regs->int_no == 1 + 32) + { + if (inb(0x60) & 0x80) + { + pic_ack(regs->int_no - 32); + return; + } + + log("ints - keyboard\n"); + } + else if (regs->int_no == 32 + 8) { + rtc_handle_interrupt(regs); + } + else if (regs->int_no == 0x80 - 32 || regs->int_no == 32) { + pit_handler(regs); + } + else if (regs->int_no == 0x80) + { + log("syscall - Hello World! Current process: %s", curr_proc->name); + } + //logln(info, "arch/ints", "Received interrupt %d\n", regs->int_no); + pic_ack(regs->int_no - 32); +} \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/io.c b/kernel/src/sys/arch/x86_64/io.c new file mode 100755 index 0000000..80b1919 --- /dev/null +++ b/kernel/src/sys/arch/x86_64/io.c @@ -0,0 +1,17 @@ +// Copyright (C) 2024 Sipaa Projects +// This code is part of the Soaplin kernel and is licensed under the terms of +// the MIT License. + +#include + +uint8_t inb(uint16_t port) { + uint8_t ret; + __asm__ volatile("inb %w1, %b0" : "=a"(ret) : "Nd"(port) : "memory"); + return ret; +} + +void outb(uint16_t port, uint8_t val) { + __asm__ volatile("outb %b0, %w1" : : "a"(val), "Nd"(port) : "memory"); +} + +void io_wait(void) { outb(0x80, 0); } \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/io.h b/kernel/src/sys/arch/x86_64/io.h new file mode 100755 index 0000000..3e41421 --- /dev/null +++ b/kernel/src/sys/arch/x86_64/io.h @@ -0,0 +1,19 @@ +// Copyright (C) 2024 Sipaa Projects +// This code is part of the Soaplin kernel and is licensed under the terms of +// the MIT License. + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +uint8_t inb(uint16_t port); +void outb(uint16_t port, uint8_t val); +void io_wait(void); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/pic.c b/kernel/src/sys/arch/x86_64/pic.c new file mode 100755 index 0000000..d36cdf9 --- /dev/null +++ b/kernel/src/sys/arch/x86_64/pic.c @@ -0,0 +1,76 @@ +//#include "sys/log.h" +#include +//#include +#include + +void pic_init() { + //if (acpi_available) + // return; + + uint8_t a1, a2; + + a1 = inb(PIC1_DATA); + a2 = inb(PIC2_DATA); + + outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); + io_wait(); + outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4); + io_wait(); + outb(PIC1_DATA, 0x20); + io_wait(); + outb(PIC2_DATA, 8); + io_wait(); + outb(PIC1_DATA, 4); + io_wait(); + outb(PIC2_DATA, 2); + io_wait(); + outb(PIC1_DATA, ICW4_8086); + io_wait(); + outb(PIC2_DATA, ICW4_8086); + io_wait(); + + outb(PIC1_DATA, a1); + outb(PIC2_DATA, a2); +} + +void pic_ack(int intno) { + if (intno >= 8) { + outb(PIC2_COMMAND, 0x20); + } + + outb(PIC1_COMMAND, 0x20); +} + +void pic_disable() // if we want APIC +{ + outb(PIC2_DATA, 0xff); + outb(PIC1_DATA, 0xff); +} + +void pic_mask_irq(uint8_t irq) { + uint16_t port; + uint8_t value; + + if (irq < 8) { + port = PIC1_DATA; + } else { + port = PIC2_DATA; + irq -= 8; + } + value = inb(port) | (1 << irq); + outb(port, value); +} + +void pic_unmask_irq(uint8_t irq) { + uint16_t port; + uint8_t value; + + if (irq < 8) { + port = PIC1_DATA; + } else { + port = PIC2_DATA; + irq -= 8; + } + value = inb(port) & ~(1 << irq); + outb(port, value); +} \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/pic.h b/kernel/src/sys/arch/x86_64/pic.h new file mode 100755 index 0000000..8365bbc --- /dev/null +++ b/kernel/src/sys/arch/x86_64/pic.h @@ -0,0 +1,23 @@ +// Copyright (C) 2024 Sipaa Projects +// This code is part of the Soaplin kernel and is licensed under the terms of +// the MIT License. + +#pragma once + +#include + +#define PIC1_COMMAND 0x20 +#define PIC1_DATA 0x21 +#define PIC2_COMMAND 0xA0 +#define PIC2_DATA 0xA1 +#define PIC_EOI 0x20 + +#define ICW1_INIT 0x10 +#define ICW1_ICW4 0x01 +#define ICW4_8086 0x01 + +void pic_init(); +void pic_ack(int intno); +void pic_disable(); // if we want APIC +void pic_mask_irq(uint8_t irq); +void pic_unmask_irq(uint8_t irq); \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/pit.c b/kernel/src/sys/arch/x86_64/pit.c new file mode 100755 index 0000000..cadfebb --- /dev/null +++ b/kernel/src/sys/arch/x86_64/pit.c @@ -0,0 +1,60 @@ +#include "sched/sched.h" +#include "sys/arch/x86_64/idt.h" +#include "sys/arch/x86_64/pic.h" +#include +#include +#ifdef __x86_64__ + +#include +#include +//#include + +uint32_t tick = 0; + +void pit_handler(registers_t *regs) +{ + tick++; + + schedule(regs); + //Scheduler_Schedule(regs); +} + +void pit_init(uint32_t frequency) +{ + uint32_t divisor = PIT_FREQUENCY / frequency; + outb(0x43, 0x34); + outb(0x40, (uint8_t)(divisor & 0xFF)); + outb(0x40, (uint8_t)((divisor >> 8) & 0xFF)); + + pic_unmask_irq(0); +} + +void sleep(uint32_t seconds) +{ + uint32_t eticks = tick + seconds * HZ; + while (tick < eticks) + { + __asm__ __volatile__("hlt"); + } +} + +void sleep_ms(uint32_t milliseconds) +{ + uint32_t eticks = tick + (milliseconds * HZ) / 1000; + while (tick < eticks) + { + __asm__ __volatile__("hlt"); + } +} + +// todo: unistd: add usleep function +void usleep(uint32_t usecs) +{ + uint32_t eticks = tick + (usecs * HZ); + while (tick < eticks) + { + __asm__ __volatile__("hlt"); + } +} + +#endif \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/pit.h b/kernel/src/sys/arch/x86_64/pit.h new file mode 100755 index 0000000..0131be8 --- /dev/null +++ b/kernel/src/sys/arch/x86_64/pit.h @@ -0,0 +1,17 @@ +#ifndef PIT_H +#define PIT_H + +#include +#include + +#define PIT_FREQUENCY 1193182 +#define HZ 1000 + +extern uint32_t tick; + +void pit_init(uint32_t frequency); +void sleep(uint32_t seconds); +void sleep_ms(uint32_t milliseconds); +void usleep(uint32_t usecs); + +#endif \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/rtc.c b/kernel/src/sys/arch/x86_64/rtc.c new file mode 100755 index 0000000..f66aec4 --- /dev/null +++ b/kernel/src/sys/arch/x86_64/rtc.c @@ -0,0 +1,25 @@ +#include "sys/arch/x86_64/idt.h" +#include "sys/arch/x86_64/io.h" +#include +#include +#include + +void rtc_init() { + asm("cli"); + outb(0x70, 0x8A); + outb(0x71, 0x20); + asm("sti"); + + asm("cli"); // disable interrupts + outb(0x70, 0x8B); // select register B, and disable NMI + char prev=inb(0x71); // read the current value of register B + outb(0x70, 0x8B); // set the index again (a read will reset the index to register D) + outb(0x71, prev | 0x40); // write the previous value ORed with 0x40. This turns on bit 6 of register B + asm("sti"); + + //pic_unmask_irq(8); +} + +void rtc_handle_interrupt(registers_t *regs) { + printf("RTC!\n"); +} \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/rtc.h b/kernel/src/sys/arch/x86_64/rtc.h new file mode 100755 index 0000000..a81996d --- /dev/null +++ b/kernel/src/sys/arch/x86_64/rtc.h @@ -0,0 +1,6 @@ +#pragma once + +#include "sys/arch/x86_64/idt.h" + +void rtc_init(); +void rtc_handle_interrupt(registers_t *regs); \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/sse.c b/kernel/src/sys/arch/x86_64/sse.c new file mode 100755 index 0000000..570d903 --- /dev/null +++ b/kernel/src/sys/arch/x86_64/sse.c @@ -0,0 +1,59 @@ +#include +#include +#include + +int cpuid_check_bit(int reg, int bit) { + int eax, ebx, ecx, edx; + + // Minimal inline assembly to execute CPUID + __asm__ volatile ( + "cpuid" // Execute CPUID instruction + : "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) // Output registers + : "a"(0x1) // Input: EAX = 0x1 (query feature flags) + : // No clobbered registers + ); + + // Check bit 25 of EDX (SSE support) in plain C + if (reg == 0) { + if (edx & (1 << bit)) { + return 1; // SSE is supported + } else { + return 0; // SSE is not supported + } + }else if (reg == 1) { + if (ecx & (1 << bit)) { + return 1; // SSE is supported + } else { + return 0; // SSE is not supported + } + } + + return 0; +} + +void sse_init() { + int sse = cpuid_check_bit(0, 25); + int sse2 = cpuid_check_bit(0, 26); + int sse3 = cpuid_check_bit(1, 0); + int ssse3 = cpuid_check_bit(1, 9); + + if (sse) + log("sse - sse is supported!\n"); + else + log("sse - sse isn't supported!\n"); + + if (sse2) + log("sse - sse2 is supported!\n"); + else + log("sse - sse2 isn't supported!\n"); + + if (sse3) + log("sse - sse3 is supported!\n"); + else + log("sse - sse3 isn't supported!\n"); + + if (ssse3) + log("sse - ssse3 is supported!\n"); + else + log("sse - ssse3 isn't supported!\n"); +} \ No newline at end of file diff --git a/kernel/src/sys/arch/x86_64/sse.h b/kernel/src/sys/arch/x86_64/sse.h new file mode 100755 index 0000000..b4500fa --- /dev/null +++ b/kernel/src/sys/arch/x86_64/sse.h @@ -0,0 +1,4 @@ +#pragma once + +int sse_is_supported(); +void sse_init(); \ No newline at end of file diff --git a/kernel/src/sys/log.c b/kernel/src/sys/log.c new file mode 100755 index 0000000..e234483 --- /dev/null +++ b/kernel/src/sys/log.c @@ -0,0 +1,32 @@ +#include "rt.h" +#include "sys/arch/x86_64/io.h" +#include +#include + +void log(char *format, ...) { + // TODO: replace this call with a call to printf() when the RTC is implemented. + rt_print("1970-01-01 00:00:00 | "); + + char buf[2048]; + va_list l; + va_start(l, format); + npf_vsnprintf(buf, 2048, format, l); + va_end(l); + + rt_print(buf); + + char *date = "1970-01-01 00:00:00 | "; + for (int i;;i++) { + if (date[i] == '\0') + break; + + outb(0xE9, date[i]); + } + + for (int i;;i++) { + if (buf[i] == '\0') + break; + + outb(0xE9, buf[i]); + } +} \ No newline at end of file diff --git a/kernel/src/sys/log.h b/kernel/src/sys/log.h new file mode 100755 index 0000000..1d9545f --- /dev/null +++ b/kernel/src/sys/log.h @@ -0,0 +1,3 @@ +#pragma once + +void log(char *format, ...); \ No newline at end of file diff --git a/kernel/src/sys/printf.c b/kernel/src/sys/printf.c new file mode 100755 index 0000000..603ab63 --- /dev/null +++ b/kernel/src/sys/printf.c @@ -0,0 +1,26 @@ +// Copyright (C) 2024 Sipaa Projects +// This code is part of the Soaplin kernel and is licensed under the terms of +// the MIT License. +#include +#include + +#define NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS 1 +#define NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS 1 +#define NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS 1 +#define NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS 0 +#define NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS 1 +#define NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS 0 + +// Compile nanoprintf in this translation unit. +#define NANOPRINTF_IMPLEMENTATION +#include + +void printf(char *format, ...) { + char buf[2048]; + va_list lst; + va_start(lst, format); + npf_vsnprintf(buf, 2048, format, lst); + va_end(lst); + + rt_print(buf); +} \ No newline at end of file diff --git a/kernel/src/sys/printf.h b/kernel/src/sys/printf.h new file mode 100755 index 0000000..759e840 --- /dev/null +++ b/kernel/src/sys/printf.h @@ -0,0 +1,1320 @@ +/* nanoprintf v0.5.3: a tiny embeddable printf replacement written in C. + https://github.com/charlesnicholson/nanoprintf + charles.nicholson+nanoprintf@gmail.com + dual-licensed under 0bsd and unlicense, take your pick. see eof for details. + */ + +#ifndef NANOPRINTF_H_INCLUDED +#define NANOPRINTF_H_INCLUDED + +#include +#include + +// Define this to fully sandbox nanoprintf inside of a translation unit. +#ifdef NANOPRINTF_VISIBILITY_STATIC +#define NPF_VISIBILITY static +#else +#define NPF_VISIBILITY extern +#endif + +#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) +#define NPF_PRINTF_ATTR(FORMAT_INDEX, VARGS_INDEX) \ + __attribute__((format(printf, FORMAT_INDEX, VARGS_INDEX))) +#else +#define NPF_PRINTF_ATTR(FORMAT_INDEX, VARGS_INDEX) +#endif + +// Public API + +#ifdef __cplusplus +extern "C" { +#endif + +// The npf_ functions all return the number of bytes required to express the +// fully-formatted string, not including the null terminator character. +// The npf_ functions do not return negative values, since the lack of 'l' +// length modifier support makes encoding errors impossible. + +NPF_VISIBILITY int npf_snprintf(char *buffer, size_t bufsz, const char *format, + ...) NPF_PRINTF_ATTR(3, 4); + +NPF_VISIBILITY int npf_vsnprintf(char *buffer, size_t bufsz, char const *format, + va_list vlist) NPF_PRINTF_ATTR(3, 0); + +typedef void (*npf_putc)(int c, void *ctx); +NPF_VISIBILITY int npf_pprintf(npf_putc pc, void *pc_ctx, char const *format, + ...) NPF_PRINTF_ATTR(3, 4); + +NPF_VISIBILITY int npf_vpprintf(npf_putc pc, void *pc_ctx, char const *format, + va_list vlist) NPF_PRINTF_ATTR(3, 0); + +#ifdef __cplusplus +} +#endif + +#endif // NANOPRINTF_H_INCLUDED + +/* The implementation of nanoprintf begins here, to be compiled only if + NANOPRINTF_IMPLEMENTATION is defined. In a multi-file library what follows + would be nanoprintf.c. */ + +#ifdef NANOPRINTF_IMPLEMENTATION + +#ifndef NANOPRINTF_IMPLEMENTATION_INCLUDED +#define NANOPRINTF_IMPLEMENTATION_INCLUDED + +#include +#include + +// The conversion buffer must fit at least UINT64_MAX in octal format with the +// leading '0'. +#ifndef NANOPRINTF_CONVERSION_BUFFER_SIZE +#define NANOPRINTF_CONVERSION_BUFFER_SIZE 23 +#endif +#if NANOPRINTF_CONVERSION_BUFFER_SIZE < 23 +#error The size of the conversion buffer must be at least 23 bytes. +#endif + +// Pick reasonable defaults if nothing's been configured. +#if !defined(NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS) && \ + !defined(NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS) && \ + !defined(NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS) && \ + !defined(NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS) && \ + !defined(NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS) && \ + !defined(NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS) +#define NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS 1 +#define NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS 1 +#define NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS 1 +#define NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS 0 +#define NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS 0 +#define NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS 0 +#endif + +// If anything's been configured, everything must be configured. +#ifndef NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS +#error NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS must be #defined to 0 or 1 +#endif +#ifndef NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS +#error NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS must be #defined to 0 or 1 +#endif +#ifndef NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS +#error NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS must be #defined to 0 or 1 +#endif +#ifndef NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS +#error NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS must be #defined to 0 or 1 +#endif +#ifndef NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS +#error NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS must be #defined to 0 or 1 +#endif +#ifndef NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS +#error NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS must be #defined to 0 or 1 +#endif + +// Ensure flags are compatible. +#if (NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1) && \ + (NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 0) +#error Precision format specifiers must be enabled if float support is enabled. +#endif + +// intmax_t / uintmax_t require stdint from c99 / c++11 +#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 +#ifndef _MSC_VER +#ifdef __cplusplus +#if __cplusplus < 201103L +#error large format specifier support requires C++11 or later. +#endif +#else +#if __STDC_VERSION__ < 199409L +#error nanoprintf requires C99 or later. +#endif +#endif +#endif +#endif + +// Figure out if we can disable warnings with pragmas. +#ifdef __clang__ +#define NANOPRINTF_CLANG 1 +#define NANOPRINTF_GCC_PAST_4_6 0 +#else +#define NANOPRINTF_CLANG 0 +#if defined(__GNUC__) && \ + ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 6))) +#define NANOPRINTF_GCC_PAST_4_6 1 +#else +#define NANOPRINTF_GCC_PAST_4_6 0 +#endif +#endif + +#if NANOPRINTF_CLANG || NANOPRINTF_GCC_PAST_4_6 +#define NANOPRINTF_HAVE_GCC_WARNING_PRAGMAS 1 +#else +#define NANOPRINTF_HAVE_GCC_WARNING_PRAGMAS 0 +#endif + +#if NANOPRINTF_HAVE_GCC_WARNING_PRAGMAS +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wimplicit-fallthrough" +#ifdef __cplusplus +#pragma GCC diagnostic ignored "-Wold-style-cast" +#endif +#pragma GCC diagnostic ignored "-Wpadded" +#pragma GCC diagnostic ignored "-Wfloat-equal" +#if NANOPRINTF_CLANG +#pragma GCC diagnostic ignored "-Wc++98-compat-pedantic" +#pragma GCC diagnostic ignored "-Wcovered-switch-default" +#pragma GCC diagnostic ignored "-Wdeclaration-after-statement" +#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" +#ifndef __APPLE__ +#pragma GCC diagnostic ignored "-Wunsafe-buffer-usage" +#endif +#elif NANOPRINTF_GCC_PAST_4_6 +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif +#endif + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4619) // there is no warning number 'number' +// C4619 has to be disabled first! +#pragma warning(disable : 4127) // conditional expression is constant +#pragma warning(disable : 4505) // unreferenced local function has been removed +#pragma warning(disable : 4514) // unreferenced inline function has been removed +#pragma warning(disable : 4701) // potentially uninitialized local variable used +#pragma warning(disable : 4706) // assignment within conditional expression +#pragma warning(disable : 4710) // function not inlined +#pragma warning(disable : 4711) // function selected for inline expansion +#pragma warning(disable : 4820) // padding added after struct member +#pragma warning(disable : 5039) // potentially throwing function passed to + // extern C function +#pragma warning(disable : 5045) // compiler will insert Spectre mitigation for + // memory load +#pragma warning(disable : 5262) // implicit switch fall-through +#pragma warning(disable : 26812) // enum type is unscoped +#endif + +#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) +#define NPF_NOINLINE __attribute__((noinline)) +#elif defined(_MSC_VER) +#define NPF_NOINLINE __declspec(noinline) +#else +#define NPF_NOINLINE +#endif + +#if (NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1) || \ + (NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1) +enum { + NPF_FMT_SPEC_OPT_NONE, + NPF_FMT_SPEC_OPT_LITERAL, + NPF_FMT_SPEC_OPT_STAR, +}; +#endif + +enum { + NPF_FMT_SPEC_LEN_MOD_NONE, + NPF_FMT_SPEC_LEN_MOD_SHORT, // 'h' + NPF_FMT_SPEC_LEN_MOD_LONG_DOUBLE, // 'L' + NPF_FMT_SPEC_LEN_MOD_CHAR, // 'hh' + NPF_FMT_SPEC_LEN_MOD_LONG, // 'l' +#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 + NPF_FMT_SPEC_LEN_MOD_LARGE_LONG_LONG, // 'll' + NPF_FMT_SPEC_LEN_MOD_LARGE_INTMAX, // 'j' + NPF_FMT_SPEC_LEN_MOD_LARGE_SIZET, // 'z' + NPF_FMT_SPEC_LEN_MOD_LARGE_PTRDIFFT, // 't' +#endif +}; + +enum { + NPF_FMT_SPEC_CONV_NONE, + NPF_FMT_SPEC_CONV_PERCENT, // '%' + NPF_FMT_SPEC_CONV_CHAR, // 'c' + NPF_FMT_SPEC_CONV_STRING, // 's' + NPF_FMT_SPEC_CONV_SIGNED_INT, // 'i', 'd' +#if NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS == 1 + NPF_FMT_SPEC_CONV_BINARY, // 'b' +#endif + NPF_FMT_SPEC_CONV_OCTAL, // 'o' + NPF_FMT_SPEC_CONV_HEX_INT, // 'x', 'X' + NPF_FMT_SPEC_CONV_UNSIGNED_INT, // 'u' + NPF_FMT_SPEC_CONV_POINTER, // 'p' +#if NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS == 1 + NPF_FMT_SPEC_CONV_WRITEBACK, // 'n' +#endif +#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 + NPF_FMT_SPEC_CONV_FLOAT_DEC, // 'f', 'F' + NPF_FMT_SPEC_CONV_FLOAT_SCI, // 'e', 'E' + NPF_FMT_SPEC_CONV_FLOAT_SHORTEST, // 'g', 'G' + NPF_FMT_SPEC_CONV_FLOAT_HEX, // 'a', 'A' +#endif +}; + +typedef struct npf_format_spec { +#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 + int field_width; + uint8_t field_width_opt; + char left_justified; // '-' + char leading_zero_pad; // '0' +#endif +#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 + int prec; + uint8_t prec_opt; +#endif + char prepend; // ' ' or '+' + char alt_form; // '#' + char case_adjust; // 'a' - 'A' + uint8_t length_modifier; + uint8_t conv_spec; +} npf_format_spec_t; + +#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 0 +typedef long npf_int_t; +typedef unsigned long npf_uint_t; +#else +typedef intmax_t npf_int_t; +typedef uintmax_t npf_uint_t; +#endif + +typedef struct npf_bufputc_ctx { + char *dst; + size_t len; + size_t cur; +} npf_bufputc_ctx_t; + +#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 +typedef char + npf_size_is_ptrdiff[(sizeof(size_t) == sizeof(ptrdiff_t)) ? 1 : -1]; +typedef ptrdiff_t npf_ssize_t; +#endif + +#ifdef _MSC_VER +#include +#endif + +static int npf_max(int x, int y) { return (x > y) ? x : y; } + +static int npf_parse_format_spec(char const *format, + npf_format_spec_t *out_spec) { + char const *cur = format; + +#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 + out_spec->left_justified = 0; + out_spec->leading_zero_pad = 0; +#endif + out_spec->case_adjust = 'a' - 'A'; // lowercase + out_spec->prepend = 0; + out_spec->alt_form = 0; + + while (*++cur) { // cur points at the leading '%' character + switch (*cur) { // Optional flags +#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 + case '-': + out_spec->left_justified = '-'; + out_spec->leading_zero_pad = 0; + continue; + case '0': + out_spec->leading_zero_pad = !out_spec->left_justified; + continue; +#endif + case '+': + out_spec->prepend = '+'; + continue; + case ' ': + if (out_spec->prepend == 0) { + out_spec->prepend = ' '; + } + continue; + case '#': + out_spec->alt_form = '#'; + continue; + default: + break; + } + break; + } + +#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 + out_spec->field_width_opt = NPF_FMT_SPEC_OPT_NONE; + if (*cur == '*') { + out_spec->field_width_opt = NPF_FMT_SPEC_OPT_STAR; + ++cur; + } else { + out_spec->field_width = 0; + while ((*cur >= '0') && (*cur <= '9')) { + out_spec->field_width_opt = NPF_FMT_SPEC_OPT_LITERAL; + out_spec->field_width = (out_spec->field_width * 10) + (*cur++ - '0'); + } + } +#endif + +#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 + out_spec->prec = 0; + out_spec->prec_opt = NPF_FMT_SPEC_OPT_NONE; + if (*cur == '.') { + ++cur; + if (*cur == '*') { + out_spec->prec_opt = NPF_FMT_SPEC_OPT_STAR; + ++cur; + } else { + if (*cur == '-') { + ++cur; + } else { + out_spec->prec_opt = NPF_FMT_SPEC_OPT_LITERAL; + } + while ((*cur >= '0') && (*cur <= '9')) { + out_spec->prec = (out_spec->prec * 10) + (*cur++ - '0'); + } + } + } +#endif + + uint_fast8_t tmp_conv = NPF_FMT_SPEC_CONV_NONE; + out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_NONE; + switch (*cur++) { // Length modifier + case 'h': + out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_SHORT; + if (*cur == 'h') { + out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_CHAR; + ++cur; + } + break; + case 'l': + out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LONG; +#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 + if (*cur == 'l') { + out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LARGE_LONG_LONG; + ++cur; + } +#endif + break; +#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 + case 'L': + out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LONG_DOUBLE; + break; +#endif +#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 + case 'j': + out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LARGE_INTMAX; + break; + case 'z': + out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LARGE_SIZET; + break; + case 't': + out_spec->length_modifier = NPF_FMT_SPEC_LEN_MOD_LARGE_PTRDIFFT; + break; +#endif + default: + --cur; + break; + } + + switch (*cur++) { // Conversion specifier + case '%': + out_spec->conv_spec = NPF_FMT_SPEC_CONV_PERCENT; +#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 + out_spec->prec_opt = NPF_FMT_SPEC_OPT_NONE; +#endif + break; + + case 'c': + out_spec->conv_spec = NPF_FMT_SPEC_CONV_CHAR; +#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 + out_spec->prec_opt = NPF_FMT_SPEC_OPT_NONE; +#endif + break; + + case 's': + out_spec->conv_spec = NPF_FMT_SPEC_CONV_STRING; +#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 + out_spec->leading_zero_pad = 0; +#endif + break; + + case 'i': + case 'd': + tmp_conv = NPF_FMT_SPEC_CONV_SIGNED_INT; + case 'o': + if (tmp_conv == NPF_FMT_SPEC_CONV_NONE) { + tmp_conv = NPF_FMT_SPEC_CONV_OCTAL; + } + case 'u': + if (tmp_conv == NPF_FMT_SPEC_CONV_NONE) { + tmp_conv = NPF_FMT_SPEC_CONV_UNSIGNED_INT; + } + case 'X': + if (tmp_conv == NPF_FMT_SPEC_CONV_NONE) { + out_spec->case_adjust = 0; + } + case 'x': + if (tmp_conv == NPF_FMT_SPEC_CONV_NONE) { + tmp_conv = NPF_FMT_SPEC_CONV_HEX_INT; + } + out_spec->conv_spec = (uint8_t)tmp_conv; +#if (NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1) && \ + (NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1) + if (out_spec->prec_opt != NPF_FMT_SPEC_OPT_NONE) { + out_spec->leading_zero_pad = 0; + } +#endif + break; + +#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 + case 'F': + out_spec->case_adjust = 0; + case 'f': + out_spec->conv_spec = NPF_FMT_SPEC_CONV_FLOAT_DEC; + if (out_spec->prec_opt == NPF_FMT_SPEC_OPT_NONE) { + out_spec->prec = 6; + } + break; + + case 'E': + out_spec->case_adjust = 0; + case 'e': + out_spec->conv_spec = NPF_FMT_SPEC_CONV_FLOAT_SCI; + if (out_spec->prec_opt == NPF_FMT_SPEC_OPT_NONE) { + out_spec->prec = 6; + } + break; + + case 'G': + out_spec->case_adjust = 0; + case 'g': + out_spec->conv_spec = NPF_FMT_SPEC_CONV_FLOAT_SHORTEST; + if (out_spec->prec_opt == NPF_FMT_SPEC_OPT_NONE) { + out_spec->prec = 6; + } + break; + + case 'A': + out_spec->case_adjust = 0; + case 'a': + out_spec->conv_spec = NPF_FMT_SPEC_CONV_FLOAT_HEX; + if (out_spec->prec_opt == NPF_FMT_SPEC_OPT_NONE) { + out_spec->prec = 6; + } + break; +#endif + +#if NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS == 1 + case 'n': + // todo: reject string if flags or width or precision exist + out_spec->conv_spec = NPF_FMT_SPEC_CONV_WRITEBACK; +#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 + out_spec->prec_opt = NPF_FMT_SPEC_OPT_NONE; +#endif + break; +#endif + + case 'p': + out_spec->conv_spec = NPF_FMT_SPEC_CONV_POINTER; +#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 + out_spec->prec_opt = NPF_FMT_SPEC_OPT_NONE; +#endif + break; + +#if NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS == 1 + case 'B': + out_spec->case_adjust = 0; + case 'b': + out_spec->conv_spec = NPF_FMT_SPEC_CONV_BINARY; + break; +#endif + + default: + return 0; + } + + return (int)(cur - format); +} + +static NPF_NOINLINE int npf_utoa_rev(npf_uint_t val, char *buf, + uint_fast8_t base, char case_adj) { + uint_fast8_t n = 0; + do { + int_fast8_t const d = (int_fast8_t)(val % base); + *buf++ = (char)(((d < 10) ? '0' : ('A' - 10 + case_adj)) + d); + ++n; + val /= base; + } while (val); + return (int)n; +} + +#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 + +#include + +#if (DBL_MANT_DIG <= 11) && (DBL_MAX_EXP <= 16) +typedef uint_fast16_t npf_double_bin_t; +typedef int_fast8_t npf_ftoa_exp_t; +#elif (DBL_MANT_DIG <= 24) && (DBL_MAX_EXP <= 128) +typedef uint_fast32_t npf_double_bin_t; +typedef int_fast8_t npf_ftoa_exp_t; +#elif (DBL_MANT_DIG <= 53) && (DBL_MAX_EXP <= 1024) +typedef uint_fast64_t npf_double_bin_t; +typedef int_fast16_t npf_ftoa_exp_t; +#else +#error Unsupported width of the double type. +#endif + +// The floating point conversion code works with an unsigned integer type of any +// size. +#ifndef NANOPRINTF_CONVERSION_FLOAT_TYPE +#define NANOPRINTF_CONVERSION_FLOAT_TYPE unsigned int +#endif +typedef NANOPRINTF_CONVERSION_FLOAT_TYPE npf_ftoa_man_t; + +#if (NANOPRINTF_CONVERSION_BUFFER_SIZE <= UINT_FAST8_MAX) && \ + (UINT_FAST8_MAX <= INT_MAX) +typedef uint_fast8_t npf_ftoa_dec_t; +#else +typedef int npf_ftoa_dec_t; +#endif + +enum { + NPF_DOUBLE_EXP_MASK = DBL_MAX_EXP * 2 - 1, + NPF_DOUBLE_EXP_BIAS = DBL_MAX_EXP - 1, + NPF_DOUBLE_MAN_BITS = DBL_MANT_DIG - 1, + NPF_DOUBLE_BIN_BITS = sizeof(npf_double_bin_t) * CHAR_BIT, + NPF_FTOA_MAN_BITS = sizeof(npf_ftoa_man_t) * CHAR_BIT, + NPF_FTOA_SHIFT_BITS = + ((NPF_FTOA_MAN_BITS < DBL_MANT_DIG) ? NPF_FTOA_MAN_BITS : DBL_MANT_DIG) - + 1 +}; + +/* Generally, floating-point conversion implementations use + grisu2 (https://bit.ly/2JgMggX) and ryu (https://bit.ly/2RLXSg0) algorithms, + which are mathematically exact and fast, but require large lookup tables. + + This implementation was inspired by Wojciech Muła's (zdjęcia@garnek.pl) + algorithm (http://0x80.pl/notesen/2015-12-29-float-to-string.html) and + extended further by adding dynamic scaling and configurable integer width by + Oskars Rubenis (https://github.com/Okarss). */ + +static int npf_ftoa_rev(char *buf, npf_format_spec_t const *spec, double f) { + char const *ret = NULL; + npf_double_bin_t bin; + { // Union-cast is UB pre-C11, compiler optimizes byte-copy loop. + char const *src = (char const *)&f; + char *dst = (char *)&bin; + for (uint_fast8_t i = 0; i < sizeof(f); ++i) { + dst[i] = src[i]; + } + } + + // Unsigned -> signed int casting is IB and can raise a signal but generally + // doesn't. + npf_ftoa_exp_t exp = + (npf_ftoa_exp_t)((npf_ftoa_exp_t)(bin >> NPF_DOUBLE_MAN_BITS) & + NPF_DOUBLE_EXP_MASK); + + bin &= ((npf_double_bin_t)0x1 << NPF_DOUBLE_MAN_BITS) - 1; + if (exp == (npf_ftoa_exp_t)NPF_DOUBLE_EXP_MASK) { // special value + ret = (bin) ? "NAN" : "FNI"; + goto exit; + } + if (spec->prec > (NANOPRINTF_CONVERSION_BUFFER_SIZE - 2)) { + goto exit; + } + if (exp) { // normal number + bin |= (npf_double_bin_t)0x1 << NPF_DOUBLE_MAN_BITS; + } else { // subnormal number + ++exp; + } + exp = (npf_ftoa_exp_t)(exp - NPF_DOUBLE_EXP_BIAS); + + uint_fast8_t carry; + carry = 0; + npf_ftoa_dec_t end, dec; + dec = (npf_ftoa_dec_t)spec->prec; + if (dec || spec->alt_form) { + buf[dec++] = '.'; + } + + { // Integer part + npf_ftoa_man_t man_i; + + if (exp >= 0) { + int_fast8_t shift_i = + (int_fast8_t)((exp > NPF_FTOA_SHIFT_BITS) ? (int)NPF_FTOA_SHIFT_BITS + : exp); + npf_ftoa_exp_t exp_i = (npf_ftoa_exp_t)(exp - shift_i); + shift_i = (int_fast8_t)(NPF_DOUBLE_MAN_BITS - shift_i); + man_i = (npf_ftoa_man_t)(bin >> shift_i); + + if (exp_i) { + if (shift_i) { + carry = (bin >> (shift_i - 1)) & 0x1; + } + exp = NPF_DOUBLE_MAN_BITS; // invalidate the fraction part + } + + // Scale the exponent from base-2 to base-10. + for (; exp_i; --exp_i) { + if (!(man_i & ((npf_ftoa_man_t)0x1 << (NPF_FTOA_MAN_BITS - 1)))) { + man_i = (npf_ftoa_man_t)(man_i << 1); + man_i = (npf_ftoa_man_t)(man_i | carry); + carry = 0; + } else { + if (dec >= NANOPRINTF_CONVERSION_BUFFER_SIZE) { + goto exit; + } + buf[dec++] = '0'; + carry = (((uint_fast8_t)(man_i % 5) + carry) > 2); + man_i /= 5; + } + } + } else { + man_i = 0; + } + end = dec; + + do { // Print the integer + if (end >= NANOPRINTF_CONVERSION_BUFFER_SIZE) { + goto exit; + } + buf[end++] = (char)('0' + (char)(man_i % 10)); + man_i /= 10; + } while (man_i); + } + + { // Fraction part + npf_ftoa_man_t man_f; + npf_ftoa_dec_t dec_f = (npf_ftoa_dec_t)spec->prec; + + if (exp < NPF_DOUBLE_MAN_BITS) { + int_fast8_t shift_f = (int_fast8_t)((exp < 0) ? -1 : exp); + npf_ftoa_exp_t exp_f = (npf_ftoa_exp_t)(exp - shift_f); + npf_double_bin_t bin_f = + bin << ((NPF_DOUBLE_BIN_BITS - NPF_DOUBLE_MAN_BITS) + shift_f); + + // This if-else statement can be completely optimized at compile time. + if (NPF_DOUBLE_BIN_BITS > NPF_FTOA_MAN_BITS) { + man_f = (npf_ftoa_man_t)(bin_f >> ((unsigned)(NPF_DOUBLE_BIN_BITS - + NPF_FTOA_MAN_BITS) % + NPF_DOUBLE_BIN_BITS)); + carry = (uint_fast8_t)((bin_f >> ((unsigned)(NPF_DOUBLE_BIN_BITS - + NPF_FTOA_MAN_BITS - 1) % + NPF_DOUBLE_BIN_BITS)) & + 0x1); + } else { + man_f = (npf_ftoa_man_t)((npf_ftoa_man_t)bin_f + << ((unsigned)(NPF_FTOA_MAN_BITS - + NPF_DOUBLE_BIN_BITS) % + NPF_FTOA_MAN_BITS)); + carry = 0; + } + + // Scale the exponent from base-2 to base-10 and prepare the first digit. + for (uint_fast8_t digit = 0; dec_f && (exp_f < 4); ++exp_f) { + if ((man_f > ((npf_ftoa_man_t)-4 / 5)) || digit) { + carry = (uint_fast8_t)(man_f & 0x1); + man_f = (npf_ftoa_man_t)(man_f >> 1); + } else { + man_f = (npf_ftoa_man_t)(man_f * 5); + if (carry) { + man_f = (npf_ftoa_man_t)(man_f + 3); + carry = 0; + } + if (exp_f < 0) { + buf[--dec_f] = '0'; + } else { + ++digit; + } + } + } + man_f = (npf_ftoa_man_t)(man_f + carry); + carry = (exp_f >= 0); + dec = 0; + } else { + man_f = 0; + } + + if (dec_f) { + // Print the fraction + for (;;) { + buf[--dec_f] = (char)('0' + (char)(man_f >> (NPF_FTOA_MAN_BITS - 4))); + man_f = (npf_ftoa_man_t)(man_f & ~((npf_ftoa_man_t)0xF + << (NPF_FTOA_MAN_BITS - 4))); + if (!dec_f) { + break; + } + man_f = (npf_ftoa_man_t)(man_f * 10); + } + man_f = (npf_ftoa_man_t)(man_f << 4); + } + if (exp < NPF_DOUBLE_MAN_BITS) { + carry &= (uint_fast8_t)(man_f >> (NPF_FTOA_MAN_BITS - 1)); + } + } + + // Round the number + for (; carry; ++dec) { + if (dec >= NANOPRINTF_CONVERSION_BUFFER_SIZE) { + goto exit; + } + if (dec >= end) { + buf[end++] = '0'; + } + if (buf[dec] == '.') { + continue; + } + carry = (buf[dec] == '9'); + buf[dec] = (char)(carry ? '0' : (buf[dec] + 1)); + } + + return (int)end; +exit: + if (!ret) { + ret = "RRE"; + } + uint_fast8_t i; + for (i = 0; ret[i]; ++i) { + buf[i] = (char)(ret[i] + spec->case_adjust); + } + return (int)i; +} + +#endif // NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS + +#if NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS == 1 +static int npf_bin_len(npf_uint_t u) { + // Return the length of the binary string format of 'u', preferring + // intrinsics. + if (!u) { + return 1; + } + +#ifdef _MSC_VER // Win64, use _BSR64 for everything. If x86, use _BSR when + // non-large. +#ifdef _M_X64 +#define NPF_HAVE_BUILTIN_CLZ +#define NPF_CLZ _BitScanReverse64 +#elif NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 0 +#define NPF_HAVE_BUILTIN_CLZ +#define NPF_CLZ _BitScanReverse +#endif +#ifdef NPF_HAVE_BUILTIN_CLZ + unsigned long idx; + NPF_CLZ(&idx, u); + return (int)(idx + 1); +#endif +#elif NANOPRINTF_CLANG || NANOPRINTF_GCC_PAST_4_6 +#define NPF_HAVE_BUILTIN_CLZ +#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 +#define NPF_CLZ(X) ((sizeof(long long) * CHAR_BIT) - (size_t)__builtin_clzll(X)) +#else +#define NPF_CLZ(X) ((sizeof(long) * CHAR_BIT) - (size_t)__builtin_clzl(X)) +#endif + return (int)NPF_CLZ(u); +#endif + +#ifndef NPF_HAVE_BUILTIN_CLZ + int n; + for (n = 0; u; ++n, u >>= 1) + ; // slow but small software fallback + return n; +#else +#undef NPF_HAVE_BUILTIN_CLZ +#undef NPF_CLZ +#endif +} +#endif + +static void npf_bufputc(int c, void *ctx) { + npf_bufputc_ctx_t *bpc = (npf_bufputc_ctx_t *)ctx; + if (bpc->cur < bpc->len) { + bpc->dst[bpc->cur++] = (char)c; + } +} + +static void npf_bufputc_nop(int c, void *ctx) { + (void)c; + (void)ctx; +} + +typedef struct npf_cnt_putc_ctx { + npf_putc pc; + void *ctx; + int n; +} npf_cnt_putc_ctx_t; + +static void npf_putc_cnt(int c, void *ctx) { + npf_cnt_putc_ctx_t *pc_cnt = (npf_cnt_putc_ctx_t *)ctx; + ++pc_cnt->n; + pc_cnt->pc(c, pc_cnt->ctx); // sibling-call optimization +} + +#define NPF_PUTC(VAL) \ + do { \ + npf_putc_cnt((int)(VAL), &pc_cnt); \ + } while (0) + +#define NPF_EXTRACT(MOD, CAST_TO, EXTRACT_AS) \ + case NPF_FMT_SPEC_LEN_MOD_##MOD: \ + val = (CAST_TO)va_arg(args, EXTRACT_AS); \ + break + +#define NPF_WRITEBACK(MOD, TYPE) \ + case NPF_FMT_SPEC_LEN_MOD_##MOD: \ + *(va_arg(args, TYPE *)) = (TYPE)pc_cnt.n; \ + break + +int npf_vpprintf(npf_putc pc, void *pc_ctx, char const *format, va_list args) { + npf_format_spec_t fs; + char const *cur = format; + npf_cnt_putc_ctx_t pc_cnt; + pc_cnt.pc = pc; + pc_cnt.ctx = pc_ctx; + pc_cnt.n = 0; + + while (*cur) { + int const fs_len = (*cur != '%') ? 0 : npf_parse_format_spec(cur, &fs); + if (!fs_len) { + NPF_PUTC(*cur++); + continue; + } + cur += fs_len; + + // Extract star-args immediately +#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 + if (fs.field_width_opt == NPF_FMT_SPEC_OPT_STAR) { + fs.field_width = va_arg(args, int); + if (fs.field_width < 0) { + fs.field_width = -fs.field_width; + fs.left_justified = 1; + } + } +#endif +#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 + if (fs.prec_opt == NPF_FMT_SPEC_OPT_STAR) { + fs.prec = va_arg(args, int); + if (fs.prec < 0) { + fs.prec_opt = NPF_FMT_SPEC_OPT_NONE; + } + } +#endif + + union { + char cbuf_mem[NANOPRINTF_CONVERSION_BUFFER_SIZE]; + npf_uint_t binval; + } u; + char *cbuf = u.cbuf_mem, sign_c = 0; + int cbuf_len = 0, need_0x = 0; +#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 + int field_pad = 0; + char pad_c = 0; +#endif +#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 + int prec_pad = 0; +#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 + int zero = 0; +#endif +#endif + + // Extract and convert the argument to string, point cbuf at the text. + switch (fs.conv_spec) { + case NPF_FMT_SPEC_CONV_PERCENT: + *cbuf = '%'; + cbuf_len = 1; + break; + + case NPF_FMT_SPEC_CONV_CHAR: + *cbuf = (char)va_arg(args, int); + cbuf_len = 1; + break; + + case NPF_FMT_SPEC_CONV_STRING: { + cbuf = va_arg(args, char *); +#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 + for (char const *s = cbuf; + ((fs.prec_opt == NPF_FMT_SPEC_OPT_NONE) || (cbuf_len < fs.prec)) && + *s; + ++s, ++cbuf_len) + ; +#else + for (char const *s = cbuf; *s; ++s, ++cbuf_len) + ; // strlen +#endif + } break; + + case NPF_FMT_SPEC_CONV_SIGNED_INT: { + npf_int_t val = 0; + switch (fs.length_modifier) { + NPF_EXTRACT(NONE, int, int); + NPF_EXTRACT(SHORT, short, int); + NPF_EXTRACT(LONG_DOUBLE, int, int); + NPF_EXTRACT(CHAR, char, int); + NPF_EXTRACT(LONG, long, long); +#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 + NPF_EXTRACT(LARGE_LONG_LONG, long long, long long); + NPF_EXTRACT(LARGE_INTMAX, intmax_t, intmax_t); + NPF_EXTRACT(LARGE_SIZET, npf_ssize_t, npf_ssize_t); + NPF_EXTRACT(LARGE_PTRDIFFT, ptrdiff_t, ptrdiff_t); +#endif + default: + break; + } + + sign_c = (val < 0) ? '-' : fs.prepend; + +#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 +#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 + zero = !val; +#endif + // special case, if prec and value are 0, skip + if (!val && (fs.prec_opt != NPF_FMT_SPEC_OPT_NONE) && !fs.prec) { + cbuf_len = 0; + } else +#endif + { + npf_uint_t uval = (npf_uint_t)val; + if (val < 0) { + uval = 0 - uval; + } + cbuf_len = npf_utoa_rev(uval, cbuf, 10, fs.case_adjust); + } + } break; + +#if NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS == 1 + case NPF_FMT_SPEC_CONV_BINARY: +#endif + case NPF_FMT_SPEC_CONV_OCTAL: + case NPF_FMT_SPEC_CONV_HEX_INT: + case NPF_FMT_SPEC_CONV_UNSIGNED_INT: { + npf_uint_t val = 0; + + switch (fs.length_modifier) { + NPF_EXTRACT(NONE, unsigned, unsigned); + NPF_EXTRACT(SHORT, unsigned short, unsigned); + NPF_EXTRACT(LONG_DOUBLE, unsigned, unsigned); + NPF_EXTRACT(CHAR, unsigned char, unsigned); + NPF_EXTRACT(LONG, unsigned long, unsigned long); +#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 + NPF_EXTRACT(LARGE_LONG_LONG, unsigned long long, unsigned long long); + NPF_EXTRACT(LARGE_INTMAX, uintmax_t, uintmax_t); + NPF_EXTRACT(LARGE_SIZET, size_t, size_t); + NPF_EXTRACT(LARGE_PTRDIFFT, size_t, size_t); +#endif + default: + break; + } + +#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 +#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 + zero = !val; +#endif + if (!val && (fs.prec_opt != NPF_FMT_SPEC_OPT_NONE) && !fs.prec) { + // Zero value and explicitly-requested zero precision means "print + // nothing". + if ((fs.conv_spec == NPF_FMT_SPEC_CONV_OCTAL) && fs.alt_form) { + fs.prec = 1; // octal special case, print a single '0' + } + } else +#endif +#if NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS == 1 + if (fs.conv_spec == NPF_FMT_SPEC_CONV_BINARY) { + cbuf_len = npf_bin_len(val); + u.binval = val; + } else +#endif + { + uint_fast8_t const base = + (fs.conv_spec == NPF_FMT_SPEC_CONV_OCTAL) + ? 8u + : ((fs.conv_spec == NPF_FMT_SPEC_CONV_HEX_INT) ? 16u : 10u); + cbuf_len = npf_utoa_rev(val, cbuf, base, fs.case_adjust); + } + + if (val && fs.alt_form && (fs.conv_spec == NPF_FMT_SPEC_CONV_OCTAL)) { + cbuf[cbuf_len++] = '0'; // OK to add leading octal '0' immediately. + } + + if (val && fs.alt_form) { // 0x or 0b but can't write it yet. + if (fs.conv_spec == NPF_FMT_SPEC_CONV_HEX_INT) { + need_0x = 'X'; + } +#if NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS == 1 + else if (fs.conv_spec == NPF_FMT_SPEC_CONV_BINARY) { + need_0x = 'B'; + } +#endif + if (need_0x) { + need_0x += fs.case_adjust; + } + } + } break; + + case NPF_FMT_SPEC_CONV_POINTER: { + cbuf_len = npf_utoa_rev((npf_uint_t)(uintptr_t)va_arg(args, void *), cbuf, + 16, 'a' - 'A'); + need_0x = 'x'; + } break; + +#if NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS == 1 + case NPF_FMT_SPEC_CONV_WRITEBACK: + switch (fs.length_modifier) { + NPF_WRITEBACK(NONE, int); + NPF_WRITEBACK(SHORT, short); + NPF_WRITEBACK(LONG, long); + NPF_WRITEBACK(LONG_DOUBLE, double); + NPF_WRITEBACK(CHAR, signed char); +#if NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS == 1 + NPF_WRITEBACK(LARGE_LONG_LONG, long long); + NPF_WRITEBACK(LARGE_INTMAX, intmax_t); + NPF_WRITEBACK(LARGE_SIZET, size_t); + NPF_WRITEBACK(LARGE_PTRDIFFT, ptrdiff_t); +#endif + default: + break; + } + break; +#endif + +#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 + case NPF_FMT_SPEC_CONV_FLOAT_DEC: + case NPF_FMT_SPEC_CONV_FLOAT_SCI: + case NPF_FMT_SPEC_CONV_FLOAT_SHORTEST: + case NPF_FMT_SPEC_CONV_FLOAT_HEX: { + double val; + if (fs.length_modifier == NPF_FMT_SPEC_LEN_MOD_LONG_DOUBLE) { + val = (double)va_arg(args, long double); + } else { + val = va_arg(args, double); + } + + sign_c = (val < 0.) ? '-' : fs.prepend; +#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 + zero = (val == 0.); +#endif + cbuf_len = npf_ftoa_rev(cbuf, &fs, val); + } break; +#endif + default: + break; + } + +#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 + // Compute the field width pad character + if (fs.field_width_opt != NPF_FMT_SPEC_OPT_NONE) { + if (fs.leading_zero_pad) { // '0' flag is only legal with numeric types + if ((fs.conv_spec != NPF_FMT_SPEC_CONV_STRING) && + (fs.conv_spec != NPF_FMT_SPEC_CONV_CHAR) && + (fs.conv_spec != NPF_FMT_SPEC_CONV_PERCENT)) { +#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 + if ((fs.prec_opt != NPF_FMT_SPEC_OPT_NONE) && !fs.prec && zero) { + pad_c = ' '; + } else +#endif + { + pad_c = '0'; + } + } + } else { + pad_c = ' '; + } + } +#endif + + // Compute the number of bytes to truncate or '0'-pad. +#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 + if (fs.conv_spec != NPF_FMT_SPEC_CONV_STRING) { +#if NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS == 1 + // float precision is after the decimal point + if (fs.conv_spec != NPF_FMT_SPEC_CONV_FLOAT_DEC) +#endif + { + prec_pad = npf_max(0, fs.prec - cbuf_len); + } + } +#endif + +#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 + // Given the full converted length, how many pad bytes? + field_pad = fs.field_width - cbuf_len - !!sign_c; + if (need_0x) { + field_pad -= 2; + } +#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 + field_pad -= prec_pad; +#endif + field_pad = npf_max(0, field_pad); + + // Apply right-justified field width if requested + if (!fs.left_justified && pad_c) { // If leading zeros pad, sign goes first. + if (pad_c == '0') { + if (sign_c) { + NPF_PUTC(sign_c); + sign_c = 0; + } + // Pad byte is '0', write '0x' before '0' pad chars. + if (need_0x) { + NPF_PUTC('0'); + NPF_PUTC(need_0x); + } + } + while (field_pad-- > 0) { + NPF_PUTC(pad_c); + } + // Pad byte is ' ', write '0x' after ' ' pad chars but before number. + if ((pad_c != '0') && need_0x) { + NPF_PUTC('0'); + NPF_PUTC(need_0x); + } + } else +#endif + { + if (need_0x) { + NPF_PUTC('0'); + NPF_PUTC(need_0x); + } + } // no pad, '0x' requested. + + // Write the converted payload + if (fs.conv_spec == NPF_FMT_SPEC_CONV_STRING) { + for (int i = 0; i < cbuf_len; ++i) { + NPF_PUTC(cbuf[i]); + } + } else { + if (sign_c) { + NPF_PUTC(sign_c); + } +#if NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS == 1 + while (prec_pad-- > 0) { + NPF_PUTC('0'); + } // int precision leads. +#endif +#if NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS == 1 + if (fs.conv_spec == NPF_FMT_SPEC_CONV_BINARY) { + while (cbuf_len) { + NPF_PUTC('0' + ((u.binval >> --cbuf_len) & 1)); + } + } else +#endif + { + while (cbuf_len-- > 0) { + NPF_PUTC(cbuf[cbuf_len]); + } + } // payload is reversed + } + +#if NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS == 1 + if (fs.left_justified && pad_c) { // Apply left-justified field width + while (field_pad-- > 0) { + NPF_PUTC(pad_c); + } + } +#endif + } + + return pc_cnt.n; +} + +#undef NPF_PUTC +#undef NPF_EXTRACT +#undef NPF_WRITEBACK + +int npf_pprintf(npf_putc pc, void *pc_ctx, char const *format, ...) { + va_list val; + va_start(val, format); + int const rv = npf_vpprintf(pc, pc_ctx, format, val); + va_end(val); + return rv; +} + +int npf_snprintf(char *buffer, size_t bufsz, const char *format, ...) { + va_list val; + va_start(val, format); + int const rv = npf_vsnprintf(buffer, bufsz, format, val); + va_end(val); + return rv; +} + +int npf_vsnprintf(char *buffer, size_t bufsz, char const *format, + va_list vlist) { + npf_bufputc_ctx_t bufputc_ctx; + bufputc_ctx.dst = buffer; + bufputc_ctx.len = bufsz; + bufputc_ctx.cur = 0; + + npf_putc const pc = buffer ? npf_bufputc : npf_bufputc_nop; + int const n = npf_vpprintf(pc, &bufputc_ctx, format, vlist); + pc('\0', &bufputc_ctx); + + if (buffer && bufsz) { +#ifdef NANOPRINTF_SNPRINTF_SAFE_EMPTY_STRING_ON_OVERFLOW + if (n >= (int)bufsz) { + buffer[0] = '\0'; + } +#else + buffer[bufsz - 1] = '\0'; +#endif + } + + return n; +} + +#if NANOPRINTF_HAVE_GCC_WARNING_PRAGMAS +#pragma GCC diagnostic pop +#endif + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // NANOPRINTF_IMPLEMENTATION_INCLUDED +#endif // NANOPRINTF_IMPLEMENTATION + +/* + nanoprintf is dual-licensed under both the "Unlicense" and the + "Zero-Clause BSD" (0BSD) licenses. The intent of this dual-licensing + structure is to make nanoprintf as consumable as possible in as many + environments / countries / companies as possible without any + encumberances. + + The text of the two licenses follows below: + + ============================== UNLICENSE ============================== + + This is free and unencumbered software released into the public domain. + + Anyone is free to copy, modify, publish, use, compile, sell, or + distribute this software, either in source code form or as a compiled + binary, for any purpose, commercial or non-commercial, and by any + means. + + In jurisdictions that recognize copyright laws, the author or authors + of this software dedicate any and all copyright interest in the + software to the public domain. We make this dedication for the benefit + of the public at large and to the detriment of our heirs and + successors. We intend this dedication to be an overt act of + relinquishment in perpetuity of all present and future rights to this + software under copyright law. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + For more information, please refer to + + ================================ 0BSD ================================= + + Copyright (C) 2019- by Charles Nicholson + + + Permission to use, copy, modify, and/or distribute this software for + any purpose with or without fee is hereby granted. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +void printf(char *format, ...); \ No newline at end of file diff --git a/limine.conf b/limine.conf new file mode 100755 index 0000000..0602bb9 --- /dev/null +++ b/limine.conf @@ -0,0 +1,12 @@ +# Timeout in seconds that Limine will use before automatically booting. +timeout: 3 +serial: yes +verbose: yes + +# The entry name that will be displayed in the boot menu. +/SILD - Soaplin 1.0 + # We use the Limine boot protocol. + protocol: limine + + # Path to the kernel to boot. boot():/ represents the partition on which limine.conf is located. + path: boot():/boot/kernel