From 44330e8427e60ab7a15d61991151a747208d73fa Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 2 May 2019 17:29:24 +0100 Subject: [PATCH] IDT --- CMakeLists.txt | 2 +- build/OwOS.bin | Bin 14916 -> 20344 bytes build/OwOS.iso | Bin 16541696 -> 16545792 bytes iso/boot/OwOS.bin | Bin 14916 -> 20344 bytes kernel.cpp | 16 ++- kernel/gdt.cpp | 15 ++- kernel/gdt.h | 4 +- kernel/idt.cpp | 81 ++++++++++++++ kernel/idt.h | 55 ++++++++++ kernel/isr.asm | 272 ++++++++++++++++++++++++++++++++++++++++++++++ kernel/isr.cpp | 68 ++++++++++++ kernel/kernio.h | 3 +- kernel/pic.cpp | 53 +++++++++ kernel/pic.h | 25 +++++ 14 files changed, 576 insertions(+), 18 deletions(-) create mode 100644 kernel/isr.asm create mode 100644 kernel/isr.cpp create mode 100644 kernel/pic.cpp create mode 100644 kernel/pic.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 74e30ef..97575b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,7 @@ set(CMAKE_ASM_COMPILER "i686-elf-as") set(CMAKE_C_COMPILER "i686-elf-gcc") set(CMAKE_CXX_COMPILER "i686-elf-g++") -set(CMAKE_CXX_FLAGS "-ffreestanding -O2 -fno-rtti -Wno-write-strings -Wno-multichar -Wno-unused-parameter -Wno-overflow -Wno-narrowing -fno-exceptions -Wno-trigraphs ${CMAKE_CXX_FLAGS}") +set(CMAKE_CXX_FLAGS "-ffreestanding -funroll-loops -O2 -fno-rtti -Wno-write-strings -Wno-multichar -Wno-unused-parameter -Wno-overflow -Wno-narrowing -fno-exceptions -Wno-trigraphs ${CMAKE_CXX_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS "-T ../linker.ld -ffreestanding -O2 -nostdlib -lgcc -Wwrite-strings ${CMAKE_EXE_LINKER_FLAGS}") include_directories(OwOS "./") diff --git a/build/OwOS.bin b/build/OwOS.bin index a0a9551e8b548068995c27225f4ca93abecf176a..6a9a4ee78a44abc68a1b6ff909f7a5c393b96f46 100755 GIT binary patch literal 20344 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 TImYQLg>ADiU+M?xq2vDmmpFKx literal 14916 zcmeHOe{@sVeZS9^!5H(TEl%qtN_bE$Avunb90NA<8iXYOh-FLl4@@Az2wSq{*p??f z1IeMpsW8zC74@>NC(GGRNpgC6c23%4r{xd`MU zkc&Vr0=Wp}B9MzfE&{m-{NF_&?}Z=ToDXxCeJ#I!g$-F)t6!xf|E15)eDO&B&ise- zFPWuO{76Oo!^`HSsS|fuao|63*RA|l!teVZg~n$88;hSUR#g*YYHR^x0Q&OOYP1fS zY|o1proLLp+h$l$mjJJRfJ*`OBEa}TOMFH!?|O|$X~L%P0}Z|Jkf3Qk7hFVCRa5dG zgg*Z?>>KZkx1cO<_tc@~fi@8BCuSn<=x)Q54s5kDv;U%U-^7{W$AA0|C76!UJKs>ozA zMu^Npo6R(t+{%)#+)n)a={J7XdZ-`|!I$uao~2=MOgN@O&)$jFen@8=M?%joiAy;YDN{zMx)e|A;5UC?Y>TmMU1-jpfAGA&;<=a?$$GX-%ZMKpP#Z4@?@t42_MEJ%n%14qGM6*|=dP)h$}awL+J=n=<+@wRAy3Fg1ww z`VD>geS*4L<2y@yn}{zA+I<`Q=Jg4V_f@M#-AvRqpei*swF)(oQX)lOSVp^_=n~OY z^J^1`Z)xWPJgNPTjQS)d3MDhs}?Y@Bdb zRu5|&+};N~TP?|cn|S7HNJHwssD2M}=)d_j)2%?nCk4Oy6O9qzI`xNe0Oab)SZJi? z)@AZ)VB6KF(NFWZ+jdj@U~zn==8@IP%&rOf$DqAV8PPXiy+>1f=7+QS&Lw-UmfZOk zu)W_Rr*DC)d{hdxaVo_GJE3)ockl~@0Q9T$Vf^Ol&T8XV455Qy!~m6Ifc{34e~k3M zim=_ckw+GxDN+9%qe-Ft0q~dN2g`VRDeCKA2lK9p{SH)S&&;WR`~ow0zlH66ckjgB zlY7;@M^E2VV8K=BWXHPK*~miHY93!fSDohZTN;t2@sG`^k4!WllHXxi?39@?eSJ{Q zrUSceOsa>5KJ{>=l_h@Dx^bEiK+Ak1-bU{6|plYCMKP{Ka`Dw?Imyd&} z99G_&-cPF*a2$Zwle&KMI2Wa90bfWQGqEH-kmBx< zPcLaBJk2@zAY+I*lJ|C!2G(%_^93uObf$I;gRDjENYbRhBlGy1n7+bcM4JbHA~B`~ z|3(Uaf-`IGFL*=qH=Y)tu0uVbP1fqPIetiUTvNP=e5C~PU8gU}dL&RP!FiHatuvEa zXFf7bzsfuFu5wyS9^R*E1u*Z6dAwxR$fY9lXcZzIPYKyEnpJvDgyxKzt`u{ED?N1= zl<|qDyK!7X$NtNb0qdKVWth+Lv!z%#tg8Hm4dH6lVe)m6k!0hR647q;wLBcbi$^H8R-;1c`|<3 zJUw}4(O7nwE5BbNnMvh>zF#r_6b>o}kh`JO>B3~Owq_jTVp-Ar@6z~+KCDiK)JOC9 zF)fRpp>fgm!iw-eR;@3DSN!Fx3YiEgmIEd>r@!XcFoiL1iok$<#TehrWbMzeo4Fsm z8CnEnn`QKU+3J|OdVUvwB~fgN9}ueF89u*p)7*GMo@B9ZK)$5<-Dr7yT2Ri*H(pt< zy*FeMUP~r^TDYG4=mq(-MVsC~$+UODan`yVr%*=@=kXVij zXDnBbm-5T~J)ux2xkQdev2a={Igo!&+@sxdZD&bw6QH~A&Vq^yt z4c~&*D{WfLI@C3^jvTZoGnh$NUJIM@(x&Bioq10;lb&x+*9q7|ST`y&w3nQd4;N36 zd%~$L`Z9v0-^6obbV^?2m>5f4GGUI7P7Pl`<%*T7 zP=B?m+PN0>%`Ug6cJv68FJ|(+%3;UUnRz6yyqB6WB{vA86T_cfm=uOrD(8|znY5{t z2?sd+O$0XexhejU83SrHCpHMx|1x|E2M!AGR_2&`nKoO=S|L5pe&*m9`RkY%S?dhC zQKKNE{S4u^YIuH(+o0k9p75Kp^&Pu(jlQpIayS<;b*U!z9Le35rLQPUpO~%hQRwq+ z^R-Ir?Bx|ws~m{R;lUoMeW<*=oYlG8ByS|p9qeY{DU&*S1M=-LsjW90yN5}44o2i~ zS1=~Afh|%bBt-)Qce0LPe^+E6D9I6t)UuslV-E(SgTemtuA!mTl~t@Y*dLPGqT!yN zU^Lh*`2&ODF4q3wU}W2%m-_E3fOjvSXBe+0V%_)*z*hVHvzD7x64@j)m+2HlKneJuhKp;H0Y&bk9 z-(AruO9O$Pa95esG~6$Tw?rax!(b@VDc>m#7>GNV&*yJ#@JJn6y+rEpNKH<+M{-KF z?XE_m@M_5tU^*JyZm)+Ee9~H9Lvx*PiBu%D)q5nD4>C=@=0?wbt&+1%s`ohE-)MKX zw0T+pw~&FBMhHmjJRKePN%hVSx76m7Y8%!=yrFdoE5Yzn5gu+~!j3}W=3fyYp*BOWc&Va}r@oBW#B#Y>afqM(M9c1fzV~do@^ND5X6fz?JE5fz?<#u0$ z9@B+Prjr!AM5`NO9WYF}b`-RF&}f;YLbzW8=bnR`0dCD4Trpx;0~{@-R7h3=t_nB@ z$7r}p;JShPY8I{@xFO)`vT*kU_Z)C7S-2tKW`O&nEZi>OOcyg5y5yolcAo@}0cXq^ z3E*?U{SLC+7sPKjjcq)CU=kymM*sQvgQpa70q|3d4IT_4XYw!XG}syGqI{!8E8uJs2 zh(0+yMb{3!d*KEh>&lw_ek3FLco_OmLO-opRLI8nct*a2heUHF z7lB*^auLWyAQypL1ac9`Md1He1k80V*J^25U32>#(#rCRa{KS?KJ8YS{;vZVqrc{B zu(m^|KZ|QH9U>U6p9~lqVk(jWV^d1SZotNALqq4Y`ApE7{MW=j$t*={7WYYJ8DQgF zz(BVH)~u4qCz+K*$9D|`5nO{``o4jKfIZaE?bE+X;Af>F%^!m4>_DG6XhmQ_H0Xl| z10F;}%7VA)6spMIZ_R-pp99m)r%{OiZw&x7!9PPye_qszz~0hZR1y6IH4smViNFfj z$EfK~1{yq%(dQKWk3XC~kKa|G$qUJwXM@T0{mC5IHV0ll2VM=>zQDrhEd0l?iu+VH zBv=qR4Q>Z)#Ezw-$3w5)N2-57@g4wK1=+tPiJ9* zF9SXYI-S1=E`pttMHWWqXM&diJ_>$1?-9J5VAwbOzX$MU*ndT*-wW7}e4#rn;$H`N z1o|lN2p$A%2TbR9f_DS9K%UOI1pgIa`u8}iboeR2^j8v8@M#`<8jTUepYnwGe+2j_ z{HHS|!T$u<0{wJ%K=2X3o8f;zhu;HC-(b+ZB7Of(FyyT|{WQsg-x%M^fcIs^o9-~~ z)bo|H&44JxEt_TmObWb z3OpFB4fh9Q%jxE}ygM9Su3y~-Vguz7=JYnyHM1s9Q$usDkJWmeb*-$)S%>>rSG~v8 z*xKI2VsfDC!OkraS&j_ofE*cO>zv+B``xQ*jfTf)II}K?Sx>i2m&7cr*Zks_V}8GD z%VWWwf#9HAuDKZMACC1_FgX|<2oDDMoipp);H?VvxFY?L;V1zPM^}F^5S>L-Z84|= z!GTEhA#O4zcZVZJt3SL&Z$@!B&YS%ay1?em&JC+NqG37MKj`m*fy#b#WCgCyJ7w0; z+|brp>u(2oMRR|6Fu0W%{KIlA9Pa8O?v=3FHS~~wtG{t;AK<%P{V`&4tZWI!f^r*r zqIs%e9sIt$k>99y`MX*>TRVx_(HfN3)@h8~huF5jkUz|c+#DfSgyl%@_Aqy{x+f^F zt8+qvdr_@*#~bP4RL82ipzIos#v)OFBo>y#kwNl_e1%W`tzq)iVQ=k?Y}2@Sx1c^i z+O?$NH|fN-3cg*fD;y?#Mf*^9Kn`l8m0AV-s%UU)Fd7SzBS@#H%(}QEL~0le%Lpv@ zB_>DvgIdHL_WE$Qu83%>;O9VOYtRTPM1Wn{8{7^Fvdx1&Fock|+BRbYt_$u(we&zXF@%|))UZ_cr zU9X9c_AxJF;h#X;D71qizI*f<%OBt0$P#0T0swl^cRH*AF!5vAVtn5N0|Z|wx_`9Z z;rk6*D#)%PhZmv}uNc|Gi>MLA3q?Tjz5o>z9)*L|LF^%pJ*7ct*FV_j&% zf?@uvH(a`8sc7|0LlM3Wu4$0Ax3_t08B#RlTe}^OYK`)RS>xGX^}-*8_SY`8L>3Kc z;;`JYuFC7-PG@ghM-8R+y+FotxTyKf>`}&2hH*zs%>A-aBWf?Nc@Gtkvr}8~i#Mv|5E;tMk*+f}O$XKf2l3 zsnl)WH@{xl&6V6KX4Sr!`>*m6G2&Kz#KhRYsG}5Zl~u6Xnp>%c+@*Sam1bG{^owwZCm}2Ue?z3b6w{6ppwpN0Fxa>Nd8{TW!x3 zn>x6itGT2F}h)a@;ijjydU1SZh9ASE@b z+C5=zS0Hs`SOJqy^ZEjDV4$#p93str6^Wo@1C>2EUG1z?M8!<+n21lXtX`drZM-hNCRySRae7Y zwu7xoYK+2?E>QFlB<=HBgC*6x7A0LXSjpr8Jsqs{FxwW^7t9lRg|P9=Nre)xYeSSw zD>s)GO5@MvC|jDSqms{Ce3Z$K`S#IHA}4FY*qorJVM;gmp@Nu0dkAB`Jx)7Z!pQe*Q@ux;b4gn>Q{=V-IWYf+`k~xmy zkQzTm>9PF0q@%@SIO?8qUh4T}=h;J`_`KBCys;c2V}Fx$^qhxsfubaiV+(}}#)0sW z7bKSNbMVZ^FGviIlHB7W z*qos45g=69WyvfMvMq4RRmtBiy~?Ih zd{yGZ`5K##@z*4o=S||6!zBsD{Q4TZnIXT6{bQc@JKO5c|1Nb;B?n{hbqQnUbvBLT z5(bKk=CB%gL(*#84Ytnq-jH;5>jqmRzBeU}giPTy^Sy*(K68_;kyf`P#fRKtH}mgX zQZt%Zj!ieZEscz&u^cD;`RxUQk>tj4c#SQRRFYG~=JigI#H*&5&1+P##B2OC4kK5J zC2v?XjU!IzACfrZ;(5a>9$at9AEM7NSN*}}IQ-A{qCbd9;85D1ploD*@+b8^JiK0s zfM@(m!b?nK(=*@xOL9R^cqmbKL_MP9Bo38g3B~Mumn~Y^ z2c!6&Uh*v^Y#IqAqKeIHI2cbUhIc8O#*9+QEquel_@`9jwB>y^jam04jBhv?|J;{2 zZC%Eu@mZNfV*>}{Rhh(T+XrkKb00_;KX5RrDMp8fY#Q?)N}O(EW1xiDVE^8aBx_td zn={%LK9aoH50BVG_SGY4$o|w?#rCH&99VO#YUxV zRn5&APbHze+Nqd$=EqMZ^>{sFbNul$i5;)@Dz@BZ&qTR%=W-n4q;g3!F7LBtLQ(Il zT+L6)C5{(!@XVttBz}_Taay}jA+sgDWM!U6jFb%4aJ@_kbc7a>iTGD~XlFS4`EJ551Cn z%%fMmJ!|hc)NF(`Q=*Swj&w7Rf9)yiuPBqFzmu;e$v*AGHd1rnHTbICOmNDV=jXoUQg$&ygQ- z`a+TwSF!d!*In(7I4pqJ>`bhz)U~Dw^ZOYp@3AwG&6Q!OoIs=*brxevUd* zex5jUa02U5ocMa2whq*zZAIo<+cQi^j>UV1X^M}X@Lr+Q$3F|3YCnscX+?cGhO@Gd#VO+9Y*8y?MB`e$lB3fWt|5ocFAXW3`wcn#ba$itj9bf5#BMh# z*DW_rTLyR9)&zGB&dwT~TRfbEbv?n<*U;hNJZ?1Yq{XNI{lDw$#t@PqF z_|S`T@3M(QCu)<@6{R(&+~+puFm&?}aDv{WIGXJo#*e;7wUEQZ>ED{-Xm)Tc;81JI^ZnKw zobGKToZOupv39pnio4Bd&Q1=?=XWZbAX8ha>$Pn;hzXG}rd-<9AVzZL=$pHgjoimO z<2luNyw(R_eYE1-y0IOH)mQDPcGpI6R*g@iRIX@od&L43Riv~BwVMfBdw>D_4`NWF`kqdCN) zqM_BQ8e+?Mh)MfkJk9G!TXl)y=p!lyG+bGOsPW}!_;w65J;#?)be_WTQ^meYaZ?hd zP2tJ$Gc3k31%t`#&;T1ugASs>Ed80oK{2kBB~;3a*Wyarc(Ic60Zyf;15hbPsFdUF zhAX*wOD!GXbVaF-c7;aIAsnrzgF1(YbEgJJW8l#-D8=nEWcr1}&m9Bh$GH>7XvcP< zMw`}&L+5-aO6LWSPXEr7PJCw$odcaIohJnxoX%Y+&bTfdo`38@+d9{UL#IVoN@qY< zjw|`Ht8%tDeTE(8(24Cv>Ev|d;1t*3_#ff$JkpQyJjahi=d>Sft3x5D-{%)9o1vHw z>3Ev+AqVmNhjdQ=@F)l8c8aPQGIpoL7I)_%c2{aeO|6;EaS2m;P#2lggF`35sA`0& zde8>f72;M-(URBMwuSK9YuHZZ8hX@Lm!MO5@>-pQUPM zF06LR^;e4ThjY(x$R+sGMc`_G4$fnLI>5aGI5gF?g2PcL_7 z@;4=vs)7@uhVFzaJBpUbk5Pk7f-uR+AZvkY(tbEEE)69Nku-0Hz%+g&HMC_owOC%n8frH}!r_Iiq4gsu%hqDnIyQW3|Ia0GaAvjh13 zNM*b@rF)LzIHZJ8)LuDZaOmDBs&s2{aFQYNV&Ks2(UKyNwIDcZOPmNebbXAZEi*p^ z&J|4^OGh^^4i23iE0IFHKseNY9L2E~2`AYKFA5Iz98bmPg~6fy3OqBRRRTDX*B7Bl07UBiXp|g`Ho#&I-s}2-2S?Vj4GMR&O zqz2~^4<{g+(&0tMq5aVkKW0v79MZ)|N<<@KIHLa;BZ+S2#LuBNQ>2ylid;>F>ir!^>?Ks+>K zI`yEONIdkKYVIKpvVuOSxRMA1e`g(i;|DG#+|5TN<%uPBXT2X>GPuU z(CAO;=;wvyp-U9UYFwWCIl)@b?Qz9p#C4CjoVOCB*9blTOybeZkJNK@za)^pl;({| zd#6dHIiY*#+8jwoyx2W7WUhpQtOoC)TXQ8A5ifcV^`A%8$P3>?1@mZwy!bujmr8MP z0AEvf@RvrZm>NABZ6B%Zlbc4zJtv$GO-YkX3i0Ck(Csvdf3uZY5=ngsepUd7u*+)C8=A z{<)!n3n?Bi{tsR!;I6(B{BIQ)kiSdK@ zT+uv})SQ_g$>)ZuYS18@kFy_u53!Pijfy#n!D>9Z)q@WUZ)3#Cl^5xUu4la)sNxhH z9uS5;|5T}CZkY^UOjTelV9(V(Two;pwZMpU@Q@q97qo;D=0@ig)ZlQV^SUmTYy)wl z^R_OPEFW>B^FGLy3+96L~F5p zu4v!Cl%oYxMBISBX*pCC+E%~MXjd#;YROWU;VCA{14H4Bfq4b$Bo`Q|0Qjh8@)Gp4ORN= zHJtY_$JbCg+z7v3Ur|L^i|}(pXTGAYgd679c`a>_8|JrlEmZ(F%wEy7R2u@>AX;aH37gSfSCsFJJ&_rWWQ8boUmen4@34MkoEUs7WT{V>%a zuH_*@te*#}`z@ttE#S`$Ev`Yd7WLV8*4(Msr_2U=Q#Xg&VVc>|?rHU7_CD}1X! z`>n8a_*V3<+*rVu8>ofiSit7&6+e6gCwbzu$uW9!L3J;*E=b!uccZlMN8I?pgpD=+ zYa_>>mTsiO%~}khwCTKf6K7~&-$do$h8TwbKykPshR1)P{8$SyY=S2INPC1EXL#gC z+8{U1u-9ff{JC+42R75;U$U8_$gW!`JYvgZ3#mO7R-S;YKM2M8FP7 z%uZ@U)`P?AJ>oqvmgBauT zsI=CD7$4Lia)TI$TPSC1c|nY)Ey{l48q0bRW5yoJnYAEBsUNuUiy!Z$wqZSf(RLqg z&|3VWG{~%mF6Qp1w5&!hy6+GSWJiTyAQj@&z>Q+Ox1V|xYf+36lh%S3B^+xpiW1IJ zUP$8215~@*ki^jkYeqRQB=K4e4mTum^e@uxFFz#l+AqovMf2i@Bu>e%(IGD+@n$}i z3x_1~H!6%NIBo$xnRQm^$+Lgi#81}h#fpe=BN6$5^yI8%S+JdYpvm1>t8 z(Af15m6#jQxaAOSiyP3`<}e-L+}w;(HC__ zAkA2%p7}KV^f*-HCXQBVQh)bg)LO7rqF}*)_^8KfaPX6ju&I3T3 zYgD@6Yf9#49nq?5O7VM~=w}{Io!===hu=ALKB>W3^E>B>?BVaUM;cz|tS_frrz2-M z59dw|j^+l3&ZHakNi&Cs^XCof0-bMi=tSJ4{4D0-+`LKKs(Xt=XZ$UtkLE3(=g>D4 zwYZ`54PZZD*HtQ_lVEmFR?KaPySw4s$~Q_l`ue6)=yqI&^A3H({}UPfHX~VaKp=DA za5=74E^f|JGW~)GnPyyWV&FV8ifVN#FtrO4U#&ax= z1Wi`_D%Abe;~wVuo`+cXs`a`?Qny;DTkSd)w>#EVtUKTjYwgD2FH9yYoXB@d-JMF7 z;dYmmh;{c^ts5`2+f%69^TiEZ_r?pcZreYtwVODRwEKxr_mliPxbB^NvF=Lib%j34 z6YA!rRbhFnq*vjNe_3lcS&;X#Q1|kvr?}mxqr`S+Td#}Tovm;qU%~Zo^YX)W{k+7w zC4X_;kKY~Yej@L1+}M^o)YYBi;WWETas2Oc=w#R6Y~$g)sloBS$DxyOkG7S=!?}4+ z*+pCydX`wz`Aqypg4qh&M!26E*$y}2t8uufH&Y2mZ`VpBz2%m&Q7l7BmA~2xJp6x6 zcw(5jz=?ufkZ%1*A3U3SIe13$J_-DPcAR0hqNSjfmL=V>R=P_gk9$<1-AhR;+@lKX zU()%7dsLxWr9|ex{@Sj1AV)tx)W)4(O)(#)Iq8}Vo z|LH5dXqqFH&)NwDkK8&`SG@1=qA7JGA$g||P;njF9QOpm*t!xK{t1K&H8|EzAh@DP zC(1YX7{YNU$`tn)LVstK^d6IY4B@D=M2C9}p>I8vxO-{l9YZLnN5!{x48awJxlmK# zokcj{LYw2AMetKg&2i5n>{hG(!&iCH6pdt)yt4?XSVMW?okJL3U*d&-#^4gg;eDAG z4QU|t74Or$=zIg(Rh)10qQR~dh4XP9&min=NR`JsU*PK|QQ@C2 z_@3hMzR-(Wxzj%2oiF&eJ8g-3zMzqZq#DFMU+}qyYJsrw{{0i@46SdIK&+D;mJ)*}CrV|xh=@jldxlG;le;70r3qbOFR{Us%F z1O0ElFDU?V1N}#Kkl2B*^KiZ;akd7B_oZGG^nuhC?^C^~-~;M`xv~9z9VrhsF;b}DBMGO2? z+CtoGKd+a1!psZnA7r5Z=f4ZM$= zJ5gD=Vg08&QGIj1?~4X?uHlXSfnRj82F2RpfN@>KeRWsm#y-zzmZ z-17yY-6!TuhSweZgubnQv`v3_>oSWl`=>t_cBenb(i zogIMBW7Z&Y&kh)RQ8Bq^2e$N*Tp8k?9hl}%>2S{u-0_!G!96<=5g?JVc6Pwc{j%T* zFFz69dOQ*Lthk2>#`c!zT0cyH9`&ZmwR(U6B?eMN?xBH8fs(-dLj$3GC}-S511D>6 zxQ7P%_N8rc4-M?^OYNR}XrOaHYSY|91G{T*xE}(BLjxWtxIa}A_vC=3ziON?Q6g(6 z2jKfG11K@>@qy9-R6_3YfrucgDem!sYeB02?c=}02hwij9v?V6kT%RcJ}_tyRX_J= zz>z^zNbb>qUcrLCI5lTGoms_DtFy7*c*Omr$%4-B}U7Al>dE&Qu>v&BkQ z4-dGX6)K%wDQvl~lv?7Q55NZr+|LV@&TkaX+;5ax;#DGt3NnULEm=QQU>i;mtsg4L zs6n*$Jz)=IKa5hecBnv#x3qSiK#F+f9v_%KoSHKCQ^F62Q&Z+16@X6(d$`{b6n!UO z_%4(5TH4yV09RBsf=bH`{Er?^(CZpRZs>mWSjrhUbpQ5PDj_#?fAly?ha0+osRoA| zx*tBCYJnTNf1w748@eAlf%41^-9JiktcC7N&*|2p_8XzA5i0SU9?04UhNVGfEmFS` za*m=s%nik#5k(blEfink-dYsC^jd@)fd6=6OA#L2Ci{k~Xac-%Aa0W9`RIp_;N5YwwCmrl{T*-ITR} zd-zIlGd!6#%eoqbuR&7afVBvGH+Qp8$$U<@o)f1!Zb*J?EY&wRB>zrq&FJNYln(bR!AIjM9d6)#&jd<`8+gCF28SC| z|9&EEiyKt`bs}wx8&uyUi4IyERL=?jtEW`Vh?!2$`nAkWmNtPAH_SdZnYPXiv%j58 zrQn9y5C53b;fC3t|5)|kh1nZZ=m_S9*~52(C1TdY>@%lRV%#wM$J42Pt%cc3Z;`k$ z^N)=+ba(;ou`{TqxB>3PH8|V=_wh5OvBwQ?ze!Q72Dpp+?%de+d$Uy1TxUJ3J##iy zwY9KzNsZiy_8Ff@q9JZX`{PfjQR0Yp{%-K>L>y>3IZdJU!XDL2yGMA4*dsVetFi9x zdZCWKNT^dJI#%m(?=wH6YT(Ab-~5bP0gij;v;V2EnVqH>E3h)wBy47zL{_Xu#Jfid zl_FQR!?L%N9-OR4$D?f_x&^sulJmf^g6y!RG?n-XJ#;lq#f)6Hyf2vmo>P1U?+CHu3>8H!{< zjmg?=HVTE!Hm#`pt2vz4H0?fDHFLiwRJ!*{Xzi6)Y24?W4`gruT-C(AM5t7fBs@zc ziIx8NoYRtFxvHJ}eWB8Q5|{=-qhh6$X4EtEK>bDhJxfA84kK2SM_pg7uVY7V>8E)cE{NYdG<2AVpmBVw zzUA{r+99OD;VMi%_3B$-(D*y#--Zj#WAdZAbn@=oFUZ^Tt@^eKMN5@JYF-Y{Rwy8h z8^ePF40?dOzC++CAfTwa+QnEKS5=u6@V`xFg>7bqU1o)SW`#p$g=1z#oy>~5nH5f% z70#Iz^)f45GAq=X6`IV7`k56CGAmp&D;j22xMfzjXI6M*R(NJsG|H@KoLSK%v!ZEc zMYGHbugr?(nHAod6)iF=T4q+X%B=9otavZ8qIG6Po6L%~nHB9aE81sPyq{UoA+zFx zyo!$X_cVX<%P&_UVf6@Cn_+MZyB&D2c)mc|&A#Ev=jh|vgLcmx4W_&)&F5~bL^86b6;GvMdcTL`^eA z`Q3K}pR8s4bziNL4Nv#eZr>yp^o4(PqLJ%~- zV!q|OLCy@;t|hC;w}TuMHrNn|9RBblB^8NW;0P-IQ zRl47iS0QRf1Mm7Cm(^L<7pO(wi_#Tzj0eJ#ZcB!0c3qaHiAzJ`n1!Z!Mi700u z_#Trrp(%qZr4Qv*P*{;Z(DKhCUw?T!noUsY%L#fX^u-h3Lo%BFm7wcQPZ_P{l!HKr zo-vdFkZKtrY_zDT!uO;MLO6Kyw{N}-Lh88u<69tukj7iQV2GNN4)XZEWUv*6HQK9^ z0U<($zViK5)(+uq(rbCI3DzuG%D_a`zYGNx zlr&`UN@~Aw(;kpjBoKQKt;~_Y@DD-lJ+-@KRV3-0QO`!&9c*wwV=cpL;-NXB38UAy z?Sf87Xv*jW((BplwBRmtDYzRSh+cLVAP;+U=;DB^Q!W`&yeS2QTF7Gpp zi7XKkmO;gk4h*G|F*x!A?L}GNVqPqBI%UWhPe4_K@rD$Xiv%N5Eb3)$!G^0Mu??uFRekYaU$ap9N|QWDruvwlA-jy!-Ju@b9m^z@|2N0ApBcgIL27M!17qcH*^H4dOYO zpMn`qCOHw*e`K)scNtH_3hE5dIaywZX#2}s!!s#b5yof@PXg%2Aq*!#x^(|g287hv z(!t<_E{8MbQ=;yoVGQp5an1GR%ii zOB%-zmr$EGp1~Vdy9E|7KgcysDlLwbTZyoaUKPb?h^(+TO=L_W#9EF_VvT>i;JH1S zrGx-|AbJ?By(P02%?YT}Yzl)K;kwIIUIz_`WvGmArSQ*sEny6A(v7K0 z<-A$IJnZC(#q+S``(@f?Y!F(M!>|a_?_Ye*m^sO`zI8ccoRU5`YG#N@s1<#|n>k;v zU_ksIf=xC;Jl|^Axz|Ylad?oxR^MTsavJm)5f&cpyFfmeoOc$yjFtql2KGP~`i)cAw12 zlhu9qjdE%hFob$?lOjft^aG;}!g1D*a!QCu`SoUoECh03i`=(cVCnuNqjkL7nZ1qC z263I=ZD&9TUk7$DR{6w5!!x)OdbCsiTw#IvfHB+zg*n3WYlA$-1W5Gro<%MZA_J@Y z9>$0#kU@JH=0;3()IP@Yl4x%3eui%&b(Z}sUsqWo4={Z;*pp@dL2a5`-9*;xe3nwN z5q?*|7;i+Fy}vTVB-D-{V%5PLZ8r}yAVioaM;K$2Kpc-UJQ#trJjUo8GWT~r&ftyA z{e4d`I3Uh_^hxb+vY``(rtU#R6meUN9z+j-I;EZ-AL*qk$X1&(10{G$_W2PaZ zb?geeBOA{%9&`79nka&iw#`S_bQL% zpldvXn)Ewk+>ph~C)XKIlSCW2HyA>ZuKDgJs~zwlmIJr6^W?fGHjrJ!s6-n2wwO1E z?D|7{US=J{+OPb{qxR@8hUJp6Q|GSSKFJ<+qk9YwL8huUCGskQ*X>#=_xXAES2|STbsiTu`+mmTGwXROS zD@UgPubp(9W!W}oMmvOqgY|T*&Ei1I6&Kw^xk||^p(Pq!Q3shlU~-n9d+KJXm>`tl zuamzZApQehy*Z%`0Xo@6IB^I+_U37CPoPe|kx!&L)<@on7I^>08~gb)?%1N|{d5H~ z*2(G#Hj@~;eE7vsn;WP|0^aGm@e z5U>$~JV)xb%jyuVHyOoXkc`ClM>8NqW_TUvg!+xq$=@3hEUO5PcQN=ucvwyQ1Wy4#5}>L02cT)PeW4u1}Ivv%rfy z#+Cq4Qk@u`{3Rag`S+$U)JOR0G?g_*@rxdq$(_-NScVpeQIC&f^e=(Hn>@Mc;>O5J zyk+r>t|Cu4C_&D?1vY(;%9TyT%}SQ52dgv?k=JmWKbE@}M6|Izg;(+TbOwazsmRFi zJT>Fs^$Z4>RCJ!j7>)$ec(&XmEKg?Z7;mwNR8984G#U1(j`MO+v$)6>MSjKrliKi} ziQOwGZ7yRVU=A%`%+sxxE1&GcXQlBhYUO-}z+}GsegRLr2h&;V!$BHnGZbjKw5@ z4A{$4;nFv-$}0a5&zQ~}W>6#V$!;HEm^10#SA~r6My9lrJE23ok1>`{ zMC~n)>u$fh&a}YV)JdiTLDcw@ybhdqiec%bjW15~AZag;+gg4)qsx}JM%0&mPAA{B zChMA2=NU6Kc_`TO8)GsgPU)8m@;Vk!5@RhvDBZcluz&Kh;qS`~n@H&j~AdJ^_*+n{MH1{TpWU(&P^5revI)=8znlfXxL>9C3 zLwaZT9}MFryKg7|WHe8_&CS0U`XP{~cNiv2`Wki^bBY zOO?nnhW8}>V0^%UkcDm5Lx!XnV)^osE?1^#3+!Srh87|9)l&w`#Bg^%V~9x@J5$bE zjNGqaK*$Qy;W^8Au>uN6mO!vhWUoaOr;u6o&imStN*J@5S- zyk&y-bME?rcjq8&E1mjprqlA^t)sv$-F$aF-v{o8x%%k zc&yECs+TV_iORofrk8IDVMDU~f5Q{Br zrI&4g3bCNKeHe9!lltd9z1&L^=i$_bp&qiu2@kGLsC8RCV_ymnL*I6Cl6md*jE4@w z^_chd@;zz-F?L{B1966nK49>MP1S-r>KPLynL@I(difhcXebbE(eWVX^?Lae7t{$s zuMP6iMGhGtht6{O5d_}^q9$D!5F#qPAe28Q5xW}PjZudzO``l5LxMn(K4iE%VsJ1d zm^$cX$Ss>x%J!F!N()Rq>{Wbkl;4}-Xi4Xs4P@Cajw-m< zhXEn>QQemTA&PeIFLz7AO0UfTz5G=KvG<@L9<|7U4BI7&{%jD#LJ0@(n#~#I1~Y~? znM+po}7XW0~@&y;JMv^GDCQ3=c^1g#mOm%WJ)o(UjgUq0^0I&gnD!?1_}A0NhO zhe&mGxL)=`ggk#e9>J?pHImU4gqX`{wlVZZO~>eEFTfCSi#^9O{4aT+3>~Lu95gA0 z{pkhc84eRG)B>l0w#ju(m|GL6=e$3JNm)J<5!Z8jB15BOQT1>VV|e3sa-$hKAWx0z z7=}5LLDyyqLkHwNq~BBqgop#rt#~h7KKM!R#m2GyUvFfZ#^?!n6&Zqd#p^lyxcLbT zlf%7dxt^$Jy`aNyrT&$y=e&yC|1m?WM5tpa4CN8X<>`zrC(3(lWQ>2Z$f-Y*XTsjI zck5cVmY_Zj*LWA?yc%eYVV$2-avETrblO^ixp(Vq4L53=}29^{M7at?EU zhRD0kTNvXKH)HwvCw;1HRFFDLx5*df1h8?t+%FKo!5y6DFYn}#dbUe1f2&2rx6fk; zNmQn>Fd(E(<2^ix&t5r%u-tK<9DoS1Zu{jBsPc;4kHH7z*o2N{#6kTPnSup(JujbA z37HDm5P9o_*ENS2=tNl?4l^L6&bA{QlR)`}@;XFWCyvSig0e0ilS4?ATgT-9p-RaK z9^~0cIfM{&)L7&Xe@py6X&y$jW8=4aQVKmWao1vgRrX@U`5&#dO6*`s#P(7uONR z48F*!Wd9#5|BQF|kN?S@^&q71FUEvJIDT`7@t6$q2O^JqY-K}4LkWum{2E*4@ z?@@~&NXRgkBU); zEId!!804EYq|RTq2H6$}9y7vwzFd2Qe3?X^yz4nIC=$2wo}+=eD+WhJ>hL%Zt80*N zVG+BDaALGW-XYC$Hn2A{kf|O+Cd{>Em5YJ#7WYsO*&t3BPzzIKBF>(~Og;Bub+i~D&3L-Tp15Nhh6xa}8Q4}Xv<1c-Zzt)~_6&URIgG7)GIHUd zqkQC&{evSPFd$@q>1Ibm4AZN?DNL<_BVwM;Am7~~B3{(XSr(?DhX#XuSD4hX@66}} z0%_gFAb+GM5AFe74f3ErQU{K6I-|I52Duj%-p2az{L0D?d2HP{J zkB2=C@@Ho}kSsR63|*KS?~NAwv&;<})w%$~b=kB4=ZHhmwcd zE3fQGd3RbOqgcL<;P0PkkiTOmYnY>x7zR$p^7YA#S&po&A^t<|Y{)v!VG6@>5Zicf zDx)3J1%9!Nc8Jmj#xc|h?S!DI(-;#esS_X1=xPG_G=VdqEXxuNTjYu+yJy+SJm%JZ z%;-1LP+khxe^2Mtd0>>=hb4c8fw3qjqt&CfRgA zcJ-!x#^^dyW!@Z4l~r>YGa{~H**4FRF4r{)W&DtW;KP zmK&fYa*M%Du2L|*P|Jm%47_&%i?%U_44FSRY?rIklDva8f0Bh21lTdw{#e96cd^?D zME~q&h)Ar!!NRCR+JVS+#$zBp;NEdBqccgz^xMa9P4EetKoqrK?i?-feJ1&cwfG+} zutF`c$Id-y*e=(-;Ft3a^7q4J!EvC#Ab%51AUA(yh)4u^a)@DJ1Of*HoRQ`TZ(?g% z$f!sjtGgbR87(<1$GwyfBOernw<(pf?m40@EvDhUXEV{{P2Mvo-lYPrVJ-!Ia`gJpYc}RC(3y`x?jP75RE%Mmpgn*(R0@35P2l(`GR5F zM3xaR8G8$0jq;&P&~sif44y#NzGn0bK;V;fZ`fN&ftG7khB0g%ugK`c*yqKYAI|t1q^^*kdLLh}g3WGER(ojg@kcL4T4rv6Wk&s3~8VzX-q_L33 zK^hNf0;C8?k&vPwO@uTF(qu@{kYXTBfix9TETlL{(;&q|N`RCIDG5?Cq>mw`K$;H8 z2x$hSnUH2dnhog_NS{Lb4ALA(b0N)xlnN;g(tJn@Af-dffV2=&CZt7>Opvl5ErzrN z(o#s-kd{IE7o;3WpF>&>$qeZWNGl-aLPC&MLRtlBHKZ>gt%39vq_vR#4QU;uuOWQ{ zX+5NGA$g@*r6t?SZrx z(mqK0A^i;L0HlMEeu0z^sQ}WikPbmQ4Cx4@LP$p;9fNcn(g{c>A)SJB8qyg^XCa+~ zbRN=gkS;*F2x(ewUq~9T3hjatdO-Q#O-G)>IsTk59kp6`97o0CdedzSs^J zw{XE|Tre5ei-12+dJmVb7w+K`_^FDLMM5(#F<=P*Mva-;-CLtr(#OYpNtk27{klU- zDjF*kS++hU@j^XY0GAZG5_*KYKA5}e`lJB30f9u;F``94#NXR5X(E(2$K}m|SbFMV zO?DnY6xrl6>lI~hVsdK!%TX(b`Pd%Ho~g+GxednB9Z!GIRQFp2e2M4`>Nrmw$!u5Me7v=;MNu{OWbfqmmjmfeJb4S!FYvsK5(ljv}+?= zS__x=gi8nE;wxM_!sTqC-3M@4U1--yDC~+aG3&K(DYWYXe*vR2T$X1I^Qjw?73|}J zg{fOI3>1`pxalE5Y!ueJylHAc*0Go@=S!IPf>KYD^CiqgR%yXq+k#R}L5U_NtHUKM zWO}jMWP1rSYHE53vsULRAY)d?PKX$Ps77%yIiR|6Z>eriwF5RX&Au=VR!1aMI%+o& z{-&j+VrAs0Ex<&>(`ir?bJX_q0=POV3T;nkzzx1GgzIAr$;1VU>;X!(<@oi%Z2#vPsdoQ!75o3WhC_P3V@yv4OKGXr^sHVOQ&nB9JH9Vc4W^3!w&*gW<~s_=dOO8wvae3|}L_e|ihPjlg$c_y#rDA7Q=FPOvpQY--C2?Uup? z22-|>`$EXA5OQmT+*d;GTOs$IklQTewg|ahI0pje!Iday58TA8-v@v9Z6Um+);kE9 z8tvs1gkLej4uSc?x8TPJ`~-$u1o)Y^;O7YZHw^z-fM0$KewDy~$M6CSPtB@#>n(&L zg761MC=>|Xt$`QX?S>4f=V!QpdJYJ=!$R(ekUJ&hP7Aq4_XsXE%6Wnd*FO_L&*8G~93bnC6AY;TLV#2ev`Y93rh5r6 zB)DQeA!?5=>s9bqcRY39@3jyd1q2s@P?sR=yIl*e5#a6w-avr=RSWJ3MTK?`pk-*F zF=Y0YO3*^PhfoZvtH97gyT658>T4nUM#$Pi9RS+F1yG%ZTsYK%o}cE*0+Se`yN5t0BQ~QH9Bld;O#NI9N?*d(D5wo3e+!;W;3)!pCWiX}e2*j8zret3g7B$; zFb^ZlAP5rNMBt0zZ=u~V_zRceZ~?W96LRB)++-maE#%^bT!N4@3b`3VZVt|+7TV1f zvP%VEHqL<#mcdnRv6~Ebxx_6J{t9b}K6ouL&ZlnrVa=he=i<^xo!7?)roLbw=Ox2@ z9AREQk_HvB8=eN{6-$DBG=;WDGN1%>+wcgUIds37oR45n3;w6!5j=mqy?{u6;5oIW zH!Req!=$sv8>rm%#tWC6>|L!fO$={~;o&^Ev)cO{Sxb^X>Vx^fndg#$+Uic(c##}d zg8w}w5W-1V3z5Yi+TFX{JGDE|RcAbfg>1=#I`F3}{A(^H4PdnmtK|J*P%F;1huSWaf-N> zC0@V@H1ul=5WF|6s7eL{8&H5J=8_h0KWa>zO`Njixlp{ZE#NiAc<({M=&^D3aZ26w zlB)vrET;0>9v0Ut+*3Yb_#u=IFBt-Y zs`G~VG)_P4oL<=@^~0=}8OM!30qht2%oOKP^4I}I^eK1m;XyFx2$p-t#xPw3;n;T9Tvj+ty^2VP|KSkgJ5-G(Kxu+GQ5qXh0N(+_tb zD|Bh>WR>h&2ep3L0)H~{)qN{VU%sxcu35kD0cFB)D^rvy?ykdsh4I&d+_uHAugNXw zUvXC`RbekC7Gu>4#X^BDU&r7S7%hs@UjQ55DNA>YcdF7K#XFnQuf;ptQY7Blm1c`~_ND3KokQ82$~ece zS(R~h%2F!h>Xs!`#yOQut&DRnn^YNBuWUkPoJ-m0%D7Z@*|5quO<8DVT>Y|vm2nNq z`c}rdmibr4H7x618Ru5kr83UFOjjA_QP!a{&aWwjbz$af_mcOiMSxHt=SjmIR>grMIP3o^5 znn$G{c03!I8simXAERCuquv-EvmcPJk9}RT2(V(*n_|>o$2i0^k2)L4LR#<+QthUe zox8sk<{(GKA$4B8H1L}0Jhya{MlpQk0Y#dVVnjGR6Bhho3y;XD*#{KxG@ezGb+S<5 zU6{5Ggz>I(p)k!K%mMO6_+lERG_AyXx5IlErj-F;cBYlZ@V786?M-#Hw`t{kxD=*& z!$SvTTEL|+EnmnKkW3^zEdwM9E`CR6EKfh8n*U}Uu#&1?_!*QPya+?4&@K&lgv)$< z*@HI;vYtKC9Y1ghfLX_~?myat_X(hkWW=XebsniUeB_95bzU=E73Qsm=`TX(g@M#K zf1nm|LN$AgGV8uNuiVsZetm#v_rP|hQ2tYJ&o-+HHSbs6HWhQC&U*zE7GMn9U(|Wm z3yN%&Pe5(Te3J>QQPeHyvd(#vNeLy{&R=0l+5MEtYu^YYo)i?@DxVVhB#GGa#1xb` zJ|Z%~#5NpL5q2-YXZ})40Cip&unjy3k~nX{4Q5p;OQD@d`$bLtE^4Y0YwCAGS@*nj zCTh~Zd_V_WSyXj;zEYic?weZVR$y|<^ZRg%KoM;pSl$9{>tF6FYUFr!hb)jAE2ZF$ ztvc@zu%|qNWqfE_At=QS8=R>b7C-$Db)6HY6<9Utg-YOVeCUjmXkgvre;Uqgq>7dRlFaZDs4JhwJm=QFf&bx+-Vbz6M7CS(B4Qt~a zJre|CIz%C*AAsFu8(T|y20OxJpvN&o#AdRc7ZP<85M5&-&w~+ylChTt#fna;CRkp_V=~Z^dCh1l7MrU6u8O4B$EkQrBB1ve^uV*@uf_{J7)z`VxQw}Tryd}9wc_V~sDZXD8o zb@aP3V<(K4LpgZpgR~8oj036TQ+=BHT~#l50la2CPJgUaXWS%g2Y0W|o>7J6f2cAA zcLS{)5rj8l;iItdVOaQHSon@u_-3N;!``np4QpGS{t$Q#hWlXgo?V^_E0_OR0johI zh0&{keibfx1H|9plGjl38kf9+5^zJq-mip`N?h_1N?ziU7f|vd{h=dK!}vp@E#nzo zvGAesfjZAAdv5hX+|lXx9Maz?O^(JZ3#*NZU;xnB)wr{(ac5WK&aTFtT}?VWTzL@p zv?&babvBrswJ>(oc?}JwhQgiovQ!Dt?{9TRG>kEk2ykprnucky5)IG;TIld$1{)}W z4i7fiLJ4&EFoPYGK!*n#?4blYe3-!jN*vM)9sT~Ev9r__kJ_0E+~xSW02}!nF!JBB zJ86t_vkqm4r7E*t{&T_Ps4P$a)4}hVF?Qkgte3{V>93T=uIaB-#t+h8*%(`;zp^zp zN`GZ%RHwhPH`)4(^TfmNn~)qc-r z{DF-zCMQ)`kmZz1t0vKpV=GO6;0Z?BA-p6M)?nF2o9e7z@jCH^QXNuWaKE|o-1!#^ z^Rs){sF(GHZd2!hX56!`wR`!``SfB3lYMre(&U;w0%lNkh7TYtJg(087I*JUuyX9G z(qF2KsfpW&+8X`SU)mYlrN6W{Hc;oaSLZpJ>SoX}_b!*&_LTXcH9ZXd3lGoi_jsd5nW;po3`?+zkNx9%FAB zXm1(?cLTue$Jm($+L=bd-2fO3V{AODJ1N-#tx3Idfk54P`ncsruvtH<)mubXhvDm>`mkVClW{*%V%%4&5 z9Ngo=1sL&I*2_X$SV45q!a5;)6n4O1)6TA0sV@s&+GaKNF%4H_53lySpw0-yUHV*| zu@(1Z6?Exha-%Y)V81j5`=#F4FM(%<9>q(zYDaL0K4G;60oODJd-xu%S!WBXJxK-Z z`h^Nj3tl!SRq(WcxyJJZ77|Y!L^90GLL>Nx^us4!bXmKOhAU7Z7?6;CNmr>ZeL1mN)41`qOz68&>> zUmuru5z5IMt;RyRCocD@P49C#y{d9T1O5f`&We&h01m{P;EHzz03monC?^EZKsjYF z;BT}gq`Z0Kpu||CA}lD-duVh*RC03kWJOS)VcxhD{T5Q*BQ<>R0PnhrLD8Q~Oo~dG z>>ZX8J$-uggRP@3f3C)yZ2$><$AGdd+EK53RBbcWG8DaLzZ(u~B()4lu7 zo)n#Ij7>^S1nikn@v)P=Lz5>ZO^yco-hoNUDM^!nk)#wwpQIVMp?*;_;*E-00PpbV zDGAYuLIWu?5*59pCVLMH52ut96%s~blF>UE6QkDZbjO}Gi18V&R%=@J!#qb5y_O^o(_w|pqD zlQJ`UGSY^YXP{}#5*tP1=WqO^=zOcX+7$-6BG5%M*rjQ27jIRDOVa=s&%Q2A2SH}M zi$(!!JjDP=irdxIu-!s_@D5Zl4$^C=e*%~E1?0mnww>VC2x%AKPD1sDls8Hpd&or- zQ0U?uaMZ;y;D`%MHJIRLNDpce^n`pqq!K7Qinl}txHPmm=z!4){tdXUxmR5s2v_{W z_)j2Rg))2(0yG64LU9G0cLt$uU|7IAKyS#m1z-^X4FXI9ZS{5W9D)V+9sm;C0z4Sf zYrtu3gF1R8dZ6(`${VOu<52RD@@~peXw#7L5s=LtT5d=Ua?z&SEmURNF0#R*4TI&1 z&;9D^(U>~?aM@HSONO%Xq(q^>dYS`e&JU`qZ{e~~7srLF02k*)HvL>QnYIBg4b$yZ zhh(bj2B^EB-Y%#Y0vv*x98t#5@&@65)qMv!1RiY!H39yyht<`%O+|orzdn$>p{(tr>gqXYyH}zoQihkev7ZWMk&jWw@N)Om47mUHadkCzKKO^_ zTM1?B-YMG*WozCk%ZIX+P=@^p{^7d#N$CqH(~%OPtOUyPq0FOJ*=r~}^|(5;Y#5Z`4JiD>jdX*uNGPjEN`$gtC>sZ5l2La6SR|Bqu zCz4VA98<0#j5&S{_&vbOLhq5EKm66$fh16tO1j1=(4|9P7j1}(w@oC{gqJt0hlk`a zz%hcm{~3LNyYJ1g@?On$LD@wp!$ThbdO$h`Wkpc-jL`B6bm?YuL0Q+OVZb|f)Y}Pj z;|NMx2NOy&TpfPikeWi-=I3bj@NzGEf4JZH938~>li~g%xo?afgqE9-YxpBK96_?* zKDCFpMll#tIHWj8Ga)U3v>wt9NClA2K)Mg0@=sG&3;5)(t>S6*x9{Y!7nFV&ejYOIG!iYP;<^NcD~4mo zgtyX!pHkt3U4Zz*a8JnNCw5${RKRxbdvJ#z>4gG&MHjfiPwi43FY=@xCO~|OSb+1R z-hoegC!hFE{u9VQX{b>|0F4HURHY&l3N&Cr*e5rDW^*Br-?rl)X5&l9;}^_Q{%go5 zD>a};0e>sxH`Idff;^7?knr;%-xMg}AEtjC^7wru{=rK@rQ$3Uc)P-z8WG_d+wI$QL!x5RZ%rltCW9%9Y?xG29)(MxX%0m0&a5fC22aalQ`Z)7)UEM$9*dJbqz{ zfACUJslcI3_#GYo;r#oM4^wFrlOT@?1VBC+G}Ic559deWJP^e073X6ik6+Q_AFiJS zdHlju%Flp&WMd7nWsE-`@;UW23h2sILSQizoNKC4JOfEELN4UfK*f08#`*P-&j$&y zYsC2-kbmN(Q8X9x1(06{aO_So{3_(}8(sXv4Bdh}jxmt(e`0)?MMp#Xq(UVW(Adlao zO8L(rpA0Go`zHAK?MyzgAms5rA1Dgc zY_B*1`E$?(*xO?K^EeL-;^`3Qi*epVqj)GX@C@==upzvl!SHIxL;M42pDHPQ|2U$WxyP_Vj|3KJlYqjDsIDUeTwVLC^YXfEV&)QtpR0C^loBIQkx z$6*0dei`I(jD(c`0`dwR8HYK<60d=RNO1h2kjETug*<*WkAGOg-H^vo0#bfICZL7T zGPu+S$A1jxp#i*t!}YH~{s~AdIkrC`uc<}h*x#IV2t)GG^ku7FQ0NVVoWtJ89A+T%zj=MO_l26DB2p5;ikz z(9AfHqdfZ}ov@xQ8lrcIkE^g{nG$N+Fof9UbCCzn0^J2<< z>UP73_$hKG`gcrumsCv0fD!yKnXd4_8PO*?20ye#kO$A1A`jD}jbSrmF$X$r_|&9X zfiqIzDUWbYs_VJ{s8g&lDJnK>l44qPN@8?;L_$<7JSGAQf_|{X-QX!!Xdjd6id?3Y zcL=~tbis%bgL?OY@~$b-@bo!78Yp3n#)3w1HKI{HFgo2Bl|nK)#U#Q9ikwp3aWr|T ztJN#IPKpQ+7ie^u8a+EcIx$ue0dxpQe&laA48s~uNCy3eYa@t&dfb?#%&Bq4spzLE z$fQ=(Hs2MN>-q~|b?x=z4OV0?5`N?=la(u@?+IH(gCO*W>W z`Cs2}g+iv5t39HpM#Q8{GDdZrZcNd2?1YR{%X^`s!4F*=VNk&TTbrX3 zQ_Gt>!XVq~t58fw1-k~hx@%#)fX^VV6EEa^^bodej}CfAHSP?zWHGl97V0KEuEZaV zJW?k}yn?qB7J2>(#e5VSTkc)Q9|E8umoWe>k1cO$hwtm7rz7lL(W%&Sja}4Wg$*@U+|v6?YuyiXtZkn=+HjGm|SalmE_3e(rVM5*ab! z569fizV(|w`Q?|Zkf5GIxY`VZTX*%fwY@_!Pq) cX+s+XQfje$8{nlu+TPygv1LfnkZ+a$55XV7AOHXW delta 63836 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

rz+QE)KGJV^Xd7rk)$RUwd@EFi}bG) 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 TImYQLg>ADiU+M?xq2vDmmpFKx literal 14916 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 #include + #include #include +#include #include +#include #include #include @@ -25,11 +28,14 @@ int kernel_main(uint32_t magic, MultibootInfo_t* multiboot) { // Init systems - int igdt = InitGDT(); - if (igdt == 1) - loggerOK("GDT Loaded"); - else + GDT_Init(); + loggerOK("GDT Init"); + + PIC_Default_Remap(); + loggerOK("PIC Remapped"); + IDT_Init(); + loggerOK("IDT Init"); Nline(); Nline(); Write("OwO, What's This?"); @@ -45,7 +51,7 @@ int kernel_main(uint32_t magic, MultibootInfo_t* multiboot) { SetFGColour(VGA_BRIGHT_MAGENTA); Write("~#"); - PanicKernel(0x00, "Self Triggered Panic", "kernel.cpp:48", "kernel_main(uint32_t magic, MultibootInfo_t* multiboot)"); + // PanicKernel(0x00, "Self Triggered Panic", "kernel.cpp:48", "kernel_main(uint32_t magic, MultibootInfo_t* multiboot)"); for (;;) asm("hlt"); diff --git a/kernel/gdt.cpp b/kernel/gdt.cpp index 755b25d..dd96191 100644 --- a/kernel/gdt.cpp +++ b/kernel/gdt.cpp @@ -25,23 +25,22 @@ void lgdt(GDT_t GDT) { asm ("lgdt %0" : : "m"(GDT)); } -int InitGDT() { +void GDT_Init() { _GDTptr.limit = (sizeof(SegmentDescriptor_t) * 5) - 1; _GDTptr.base = (uint32_t)&_GDT; // Null segment - SetGDTGate(0, 0, 0, 0, 0); - // Code Base 0 limit 32 Access EXEC + RW - SetGDTGate(1, 0x00000000, 0xFFFFFFFF, GDT_ACCESS_PRESENT | GDT_ACCESS_EXEC | GDT_ACCESS_RW, GDT_FLAG_GR_PAGE | GDT_FLAG_SZ_32B); - // Data Base 0 Limit 32 Access RW - SetGDTGate(2, 0x00000000, 0xFFFFFFFF, GDT_ACCESS_PRESENT | GDT_ACCESS_RW, GDT_FLAG_GR_PAGE | GDT_FLAG_SZ_32B); + GDT_Set_Gate(0, 0, 0, 0, 0); + // Code Base 0 limit 32 Access EXEC + RW + GDT_Set_Gate(1, 0x00000000, 0xFFFFFFFF, GDT_ACCESS_PRESENT | GDT_ACCESS_EXEC | GDT_ACCESS_RW, GDT_FLAG_GR_PAGE | GDT_FLAG_SZ_32B); + // Data Base 0 Limit 32 Access RW + GDT_Set_Gate(2, 0x00000000, 0xFFFFFFFF, GDT_ACCESS_PRESENT | GDT_ACCESS_RW, GDT_FLAG_GR_PAGE | GDT_FLAG_SZ_32B); lgdt(_GDTptr); SEGMENTS_RELOAD(); - return 1; } -void SetGDTGate(uint32_t index, uint32_t baseAddr, uint32_t limitAddr, uint8_t accessLvl, uint8_t flags) { +void GDT_Set_Gate(uint32_t index, uint32_t baseAddr, uint32_t limitAddr, uint8_t accessLvl, uint8_t flags) { if (index > 5) return; _GDT[index].base_low = (baseAddr & 0xFFFF); _GDT[index].base_middle = (baseAddr >> 16) & 0xFF; diff --git a/kernel/gdt.h b/kernel/gdt.h index 0b0a08a..2763a01 100644 --- a/kernel/gdt.h +++ b/kernel/gdt.h @@ -19,5 +19,5 @@ extern "C" { extern void SEGMENTS_RELOAD(void); } -int InitGDT(); -void SetGDTGate(uint32_t index, uint32_t baseAddr, uint32_t limitAddr, uint8_t accessLvl, uint8_t flags); +void GDT_Init(); +void GDT_Set_Gate(uint32_t index, uint32_t baseAddr, uint32_t limitAddr, uint8_t accessLvl, uint8_t flags); diff --git a/kernel/idt.cpp b/kernel/idt.cpp index e69de29..8654f5d 100644 --- a/kernel/idt.cpp +++ b/kernel/idt.cpp @@ -0,0 +1,81 @@ +#include "idt.h" + +#include +#include + +struct IDT_Descriptor_t { + uint16_t offset_low; + uint16_t selector; + uint8_t zero; + uint8_t type_attr; + uint16_t offset_high; +} __attribute__((packed)); + +struct IDT_t { + uint16_t limit; + uint32_t base; +} __attribute__((packed)); + + +IDT_Descriptor_t _IDT[256]; +IDT_t _IDTptr; + +void lidt(IDT_t IDT) { + asm("lidt %0" : : "m"(IDT)); +} + +void IDT_Set_Gate(uint8_t i, uint32_t offset, uint16_t selector, uint8_t attrib); + +void IDT_Init() { + _IDTptr.limit = (sizeof(IDT_Descriptor_t) * 256) - 1; + _IDTptr.base = (uint32_t)&_IDT; + + for (uint16_t i = 0; i < 256; i++) + IDT_Set_Gate(i, (uint32_t)&ISR_DEFAULT, 0x01, IDT_ATTR_PRESENT | IDT_TRAP_GATE | IDT_ATTR_PRIV_3); + + IDT_Set_Gate(0x00, (uint32_t)&ISR0, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x01, (uint32_t)&ISR1, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x02, (uint32_t)&ISR2, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x03, (uint32_t)&ISR3, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x04, (uint32_t)&ISR4, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x05, (uint32_t)&ISR5, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x06, (uint32_t)&ISR6, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x07, (uint32_t)&ISR7, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x08, (uint32_t)&ISR8, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x09, (uint32_t)&ISR9, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x0A, (uint32_t)&ISR10, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x0B, (uint32_t)&ISR11, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x0C, (uint32_t)&ISR12, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x0D, (uint32_t)&ISR13, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x0E, (uint32_t)&ISR14, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x0F, (uint32_t)&ISR15, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x10, (uint32_t)&ISR16, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x11, (uint32_t)&ISR17, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x12, (uint32_t)&ISR18, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x13, (uint32_t)&ISR19, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x14, (uint32_t)&ISR20, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x15, (uint32_t)&ISR21, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x16, (uint32_t)&ISR22, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x17, (uint32_t)&ISR23, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x18, (uint32_t)&ISR24, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x19, (uint32_t)&ISR25, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x1A, (uint32_t)&ISR26, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x1B, (uint32_t)&ISR27, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x1C, (uint32_t)&ISR28, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x1D, (uint32_t)&ISR29, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x1E, (uint32_t)&ISR30, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + IDT_Set_Gate(0x1F, (uint32_t)&ISR31, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + + IDT_Set_Gate(0x21, (uint32_t)&ISR_KBD, 0x01, IDT_ATTR_PRESENT | IDT_INT_GATE); + + lidt(_IDTptr); +} + +void IDT_Set_Gate(uint8_t i, uint32_t offset, uint16_t selector, uint8_t attrib) { + if (i > 256) return; + _IDT[i].offset_low = offset & 0xFFFF; + _IDT[i].selector = selector * 8; + _IDT[i].zero = 0; + _IDT[i].type_attr = attrib; + _IDT[i].offset_high = (offset & 0xFFFF) >> 16; +} diff --git a/kernel/idt.h b/kernel/idt.h index e69de29..6bfd739 100644 --- a/kernel/idt.h +++ b/kernel/idt.h @@ -0,0 +1,55 @@ +#pragma once + +#include + +#define IDT_ATTR_PRESENT 0x80 +#define IDT_ATTR_PRIV_3 0x60 +#define IDT_ATTR_PRIV_2 0x40 +#define IDT_ATTR_PRIV_1 0x20 +#define IDT_INT_GATE 0x0E +#define IDT_TRAP_GATE 0x0F +#define IDT_TASK_GATE 0x15 + + +void IDT_Init(); +void IDT_Set_Gate(); + +#define ISR_DEF(id) extern void ISRid(void) + +extern "C" { + extern void ISR_DEFAULT(void); + extern void ISR_KBD(void); + + extern void ISR0(void); + extern void ISR1(void); + extern void ISR2(void); + extern void ISR3(void); + extern void ISR4(void); + extern void ISR5(void); + extern void ISR6(void); + extern void ISR7(void); + extern void ISR8(void); + extern void ISR9(void); + extern void ISR10(void); + extern void ISR11(void); + extern void ISR12(void); + extern void ISR13(void); + extern void ISR14(void); + extern void ISR15(void); + extern void ISR16(void); + extern void ISR17(void); + extern void ISR18(void); + extern void ISR19(void); + extern void ISR20(void); + extern void ISR21(void); + extern void ISR22(void); + extern void ISR23(void); + extern void ISR24(void); + extern void ISR25(void); + extern void ISR26(void); + extern void ISR27(void); + extern void ISR28(void); + extern void ISR29(void); + extern void ISR30(void); + extern void ISR31(void); +} diff --git a/kernel/isr.asm b/kernel/isr.asm new file mode 100644 index 0000000..12c908c --- /dev/null +++ b/kernel/isr.asm @@ -0,0 +1,272 @@ +.align 4 +.global ISR0 +.global ISR1 +.global ISR2 +.global ISR3 +.global ISR4 +.global ISR5 +.global ISR6 +.global ISR7 +.global ISR8 +.global ISR9 +.global ISR10 +.global ISR11 +.global ISR12 +.global ISR13 +.global ISR14 +.global ISR15 +.global ISR16 +.global ISR17 +.global ISR18 +.global ISR19 +.global ISR20 +.global ISR21 +.global ISR22 +.global ISR23 +.global ISR24 +.global ISR25 +.global ISR26 +.global ISR27 +.global ISR28 +.global ISR29 +.global ISR30 +.global ISR31 + +ISR0: + cli + push $0 + push $0 + jmp ISR_FAULT + +ISR1: + cli + push $0 + push $1 + jmp ISR_FAULT + +ISR2: + cli + push $0 + push $2 + jmp ISR_FAULT + +ISR3: + cli + push $0 + push $3 + jmp ISR_FAULT + +ISR4: + cli + push $0 + push $4 + jmp ISR_FAULT + +ISR5: + cli + push $0 + push $5 + jmp ISR_FAULT + +ISR6: + cli + push $0 + push $6 + jmp ISR_FAULT + +ISR7: + cli + push $0 + push $7 + jmp ISR_FAULT + +ISR8: + cli + push $8 + jmp ISR_FAULT + +ISR9: + cli + push $9 + jmp ISR_FAULT + +ISR10: + cli + push $10 + jmp ISR_FAULT + +ISR11: + cli + push $11 + jmp ISR_FAULT + +ISR12: + cli + push $12 + jmp ISR_FAULT + +ISR13: + cli + push $13 + jmp ISR_FAULT + +ISR14: + cli + push $14 + jmp ISR_FAULT + +ISR15: + cli + push $15 + jmp ISR_FAULT + +ISR16: + cli + push $16 + jmp ISR_FAULT + +ISR17: + cli + push $17 + jmp ISR_FAULT + +ISR18: + cli + push $18 + jmp ISR_FAULT + +ISR19: + cli + push $19 + jmp ISR_FAULT + +ISR20: + cli + push $20 + jmp ISR_FAULT + +ISR21: + cli + push $21 + jmp ISR_FAULT + +ISR22: + cli + push $22 + jmp ISR_FAULT + +ISR23: + cli + push $23 + jmp ISR_FAULT + +ISR24: + cli + push $24 + jmp ISR_FAULT + +ISR25: + cli + push $25 + jmp ISR_FAULT + +ISR26: + cli + push $26 + jmp ISR_FAULT + +ISR27: + cli + push $27 + jmp ISR_FAULT + +ISR28: + cli + push 28 + jmp ISR_FAULT + +ISR29: + cli + push $29 + jmp ISR_FAULT + +ISR30: + cli + push $30 + jmp ISR_FAULT + +ISR31: + cli + push $31 + jmp ISR_FAULT + +.extern FaultHandler +ISR_FAULT: + pusha + push %ds + push %es + push %fs + push %gs + movw $0x10,%ax + movw %ax,%ds + movw %ax,%es + movw %ax,%fs + movw %ax,%gs + movl %esp,%eax + pushl %eax + call FaultHandler + popl %eax + popl %gs + popl %fs + popl %es + popl %ds + popa + addl $8,%esp + iret + +.global ISR_DEFAULT +.extern DEFAULT_ISR +ISR_DEFAULT: + pushal + pushw %ds + pushw %es + pushw %fs + pushw %gs + pushl %ebx + movw $0x10,%bx + movw %bx,%ds + popl %ebx + + cld /* C code following the sysV ABI requires DF to be clear on function entry */ + call DEFAULT_ISR + + popw %gs + popw %fs + popw %es + popw %ds + popal + iret + +.global ISR_KBD +.extern KeyboardHandler +ISR_KBD: + pushal + pushw %ds + pushw %es + pushw %fs + pushw %gs + pushl %ebx + movw $0x10,%bx + movw %bx,%ds + popl %ebx + + cld /* C code following the sysV ABI requires DF to be clear on function entry */ + call KeyboardHandler + + popw %gs + popw %fs + popw %es + popw %ds + popal + iret + diff --git a/kernel/isr.cpp b/kernel/isr.cpp new file mode 100644 index 0000000..45fdf30 --- /dev/null +++ b/kernel/isr.cpp @@ -0,0 +1,68 @@ + +#include +#include +#include + +struct Regs_t { + unsigned int gs, fs, es, ds; /* pushed the segs last */ + unsigned int edi, esi, ebp, esp, ebx, edx, ecx, eax; /* pushed by 'pusha' */ + unsigned int int_no, err_code; /* our 'push byte #' and ecodes do this */ + unsigned int eip, cs, eflags, useresp, ss; /* pushed by the processor automatically */ +}; + +char *PanicMessage[] = { + "Division By Zero", + "Debug", + "Non Maskable Interrupt", + "Break Point", + "Into Detect Overflow", + "Out of bounds Exception", + "Invalid Opcode", + "No Coprocessor", + "Double Fault", + "Coprocessor Segment Overrun", + "Bad TSS Exception", + "Segment not present", + "Stack Fault", + "General Protection Fault", + "Page Fault", + "Unknown Interrupt", + "Coprocessor Fault", + "Alignement Check Exception", + "Machine Check Exception", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved", + "Reserved" +}; + +extern "C" { + +void DEFAULT_ISR() { + Write("SMH \n"); + outb(0x20,0x20); +} + +void KeyboardHandler() { + Write("Keyboard Pressed! \n"); + outb(0x20,0x20); +} + +void FaultHandler(struct Regs_t *r) { + uint32_t val; + asm volatile ( "mov %%cr2, %0" : "=r"(val) ); + PanicKernel(val, PanicMessage[r->int_no]); + for (;;) + asm("hlt"); +} + +} diff --git a/kernel/kernio.h b/kernel/kernio.h index 440fdd0..da9ef25 100644 --- a/kernel/kernio.h +++ b/kernel/kernio.h @@ -38,8 +38,7 @@ static inline void outl(uint16_t port, uint32_t val) { asm ( "outl %0, %1" : : "a"(val), "Nd"(port) ); } -static inline void io_wait(void) { - /* TODO: This is probably fragile. */ +static inline void io_wait() { asm ( "jmp 1f\n\t" "1:jmp 2f\n\t" "2:" ); diff --git a/kernel/pic.cpp b/kernel/pic.cpp new file mode 100644 index 0000000..42238ba --- /dev/null +++ b/kernel/pic.cpp @@ -0,0 +1,53 @@ +#include "pic.h" + +#include + +void PIC_Default_Remap() { + outb(0x20, 0x11); + io_wait(); + outb(0xA0, 0x11); + io_wait(); + outb(0x21, 0x20); + io_wait(); + outb(0xA1, 0x28); + io_wait(); + outb(0x21, 0x04); + io_wait(); + outb(0xA1, 0x02); + io_wait(); + outb(0x21, 0x01); + io_wait(); + outb(0xA1, 0x01); + io_wait(); + outb(0x21, 0x0); + io_wait(); + outb(0xA1, 0x0); +} + +void PIC_Remap(int offset1, int offset2) { + unsigned char a1, a2; + + a1 = inb(PIC1_DATA); // save masks + a2 = inb(PIC2_DATA); + + outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); // starts the initialization sequence (in cascade mode) + io_wait(); + outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4); + io_wait(); + outb(PIC1_DATA, offset1); // ICW2: Master PIC vector offset + io_wait(); + outb(PIC2_DATA, offset2); // ICW2: Slave PIC vector offset + io_wait(); + outb(PIC1_DATA, 4); // ICW3: tell Master PIC that there is a slave PIC at IRQ2 (0000 0100) + io_wait(); + outb(PIC2_DATA, 2); // ICW3: tell Slave PIC its cascade identity (0000 0010) + io_wait(); + + outb(PIC1_DATA, ICW4_8086); + io_wait(); + outb(PIC2_DATA, ICW4_8086); + io_wait(); + + outb(PIC1_DATA, a1); // restore saved masks. + outb(PIC2_DATA, a2); +} diff --git a/kernel/pic.h b/kernel/pic.h new file mode 100644 index 0000000..9ad06eb --- /dev/null +++ b/kernel/pic.h @@ -0,0 +1,25 @@ +#pragma once + +#define PIC1 0x20 /* IO base address for master PIC */ +#define PIC2 0xA0 /* IO base address for slave PIC */ +#define PIC1_COMMAND PIC1 +#define PIC1_DATA (PIC1+1) +#define PIC2_COMMAND PIC2 +#define PIC2_DATA (PIC2+1) + +#define PIC_EOI 0x20 /* End-of-interrupt command code */ + +#define ICW1_ICW4 0x01 /* ICW4 (not) needed */ +#define ICW1_SINGLE 0x02 /* Single (cascade) mode */ +#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */ +#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */ +#define ICW1_INIT 0x10 /* Initialization - required! */ + +#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */ +#define ICW4_AUTO 0x02 /* Auto (normal) EOI */ +#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */ +#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */ +#define ICW4_SFNM 0x10 /* Special fully nested (not) */ + +void PIC_Default_Remap(); +void PIC_Remap(int offset1, int offset2);