hschumann2/TempleOS-Source-Code
0838
1 2asm {3USE324 5SYS_PCIBIOS_SERVICE_DIR:: DU32 0;6SYS_PCI_SERVICES:: DU32 0;7 8SYS_FIND_PCIBIOS_SERVICE_DIR::9 MOV ESI,0xE000010 MOV ECX,(0x100000-0xE0000)/411@@05: CMP U32 [ESI],'_32_'12 JNE @@2013 PUSH ECX14 XOR ECX,ECX15 MOV CL,U8 9[ESI]16 SHL ECX,417@@10: MOV EDI,ESI18 XOR EAX,EAX19 XOR EDX,EDX20@@15: MOV DL,U8 [EDI]21 ADD EAX,EDX22 INC EDI23 DEC ECX24 JNZ @@1525 POP ECX26 TEST AL,AL27 JNZ @@2028 MOV U32 [SYS_PCIBIOS_SERVICE_DIR],ESI29 MOV ESI,U32 4[ESI]30 MOV U32 [SYS_PCIBIOS_SERVICE_CALL],ESI31 RET32 33@@20: ADD ESI,434 LOOP @@0535 MOV U32 [SYS_PCIBIOS_SERVICE_DIR],036 RET37 38SYS_FIND_PCI_SERVICES::39 MOV ESI,U32 [SYS_PCIBIOS_SERVICE_DIR]40 TEST ESI,ESI41 JNZ @@0542 MOV U32 [SYS_PCI_SERVICES],043 RET44@@05: MOV EAX,'$PCI'45 XOR EBX,EBX46 DU8 0x9A; //CALL CGDT.cs32:PCIBIOS_SERVICE47SYS_PCIBIOS_SERVICE_CALL:: DU32 0;48 DU16 CGDT.cs32;49 TEST AL,AL50 JNZ @@0551 LEA ESI,U32 [EBX+EDX]52 MOV U32 [SYS_PCI_SERVICES],ESI53 RET54 55@@05: MOV U32 [SYS_PCI_SERVICES],056 RET57 58USE6459C32_EAX:: DU32 0;60C32_EBX:: DU32 0;61C32_ECX:: DU32 0;62C32_EDX:: DU32 0;63C32_ESI:: DU32 0;64C32_EDI:: DU32 0;65C32_EFLAGS:: DU32 0;66 67C32_RSP:: DU64 0;68 69_FAR_CALL32::70//This calls a 32-bit mode routine.71//(We must switch from 64-bit mode to do it.)72//73//NON REENTRANT74//75 PUSH RBP76 MOV RBP,RSP77 MOV RAX,U64 SF_ARG1[RBP]78 TEST RAX,RAX79 JNZ @@0580 POP RBP81 RET1 8 //return FALSE82@@05: MOV U32 [C32_ADD],EAX83 PUSH_REGS84 PUSHFD85 XOR RAX,RAX86 PUSH U64 FS:CTask.addr[RAX]87 PUSH U64 GS:CCPU.addr[RAX]88 MOV U64 [C32_RSP],RSP89 PUSH U32 CGDT.ds //STKSEG90 PUSH U32 BOOT_RAM_LIMIT //STK91 PUSH U32 0 //FLAGS--interrupts off92 PUSH U32 CGDT.cs3293 LEA RAX,[@@15]94 PUSH RAX95 IRET96USE3297@@15:98 WBINVD99//disable paging100 MOV_EAX_CR0101 BTR EAX,31102 MOV_CR0_EAX103 104 MOV ECX,IA32_EFER105 XOR EDX,EDX106 XOR EAX,EAX107 WRMSR108 109 MOV AX,CGDT.ds110 MOV FS,AX111 MOV GS,AX112//SS already set113 114 MOV EAX,U32 [C32_EAX]115 MOV EBX,U32 [C32_EBX]116 MOV ECX,U32 [C32_ECX]117 MOV EDX,U32 [C32_EDX]118 MOV ESI,U32 [C32_ESI]119 MOV EDI,U32 [C32_EDI]120 MOV U32 [C32_EFLAGS],0121 122 DU8 0x9A; //CALL CGDT.cs32:[C32_ADD]123C32_ADD:: DU32 0;124 DU16 CGDT.cs32;125 126 PUSHFD127 POP U32 [C32_EFLAGS]128 129 MOV U32 [C32_EAX],EAX130 MOV U32 [C32_EBX],EBX131 MOV U32 [C32_ECX],ECX132 MOV U32 [C32_EDX],EDX133 MOV U32 [C32_ESI],ESI134 MOV U32 [C32_EDI],EDI135 136 PUSH U32 0 //Return from next call will be 64-bit137 CALL SYS_ENTER_LONG_MODE138 139USE64 MOV RSP,U64 [C32_RSP]140 POP RAX141 CALL SET_GS_BASE142 POP RAX143 CALL SET_FS_BASE144 145 POPFD146 POP_REGS147 XOR RAX,RAX148 MOV AL,TRUE149 POP RBP150 RET1 8151}152 153_extern C32_EAX U32 c32_eax;154_extern C32_EBX U32 c32_ebx;155_extern C32_ECX U32 c32_ecx;156_extern C32_EDX U32 c32_edx;157_extern C32_ESI U32 c32_esi;158_extern C32_EDI U32 c32_edi;159_extern C32_EFLAGS U32 c32_eflags;160_extern SYS_PCI_SERVICES U32 sys_pci_services;161 162_extern _FAR_CALL32 Bool FarCall32(U0 (*fp_addr)());//Not reentrant.For PCIBIOS.163 164U8 PCIReadU8(I64 bus,I64 dev,I64 fun,I64 rg)165{//Read U8 in PCI configspace at bus,dev,fun,reg.166 I64 res;167 PUSHFD168 CLI169 while (LBts(&sys_semas[SEMA_FAR_CALL32],0))170 Yield;171 c32_eax=0xB108;172 c32_ebx=bus<<8+dev<<3+fun;173 c32_edi=rg;174 if (FarCall32(sys_pci_services))175 res=c32_ecx.u8[0];176 else177 res=0xFF;178 LBtr(&sys_semas[SEMA_FAR_CALL32],0);179 POPFD180 return res;181}182 183U16 PCIReadU16(I64 bus,I64 dev,I64 fun,I64 rg)184{//Read U16 in PCI configspace at bus,dev,fun,reg.185 I64 res;186 PUSHFD187 CLI188 while (LBts(&sys_semas[SEMA_FAR_CALL32],0))189 Yield;190 c32_eax=0xB109;191 c32_ebx=bus<<8+dev<<3+fun;192 c32_edi=rg;193 if (FarCall32(sys_pci_services))194 res=c32_ecx.u16[0];195 else196 res=0xFFFF;197 LBtr(&sys_semas[SEMA_FAR_CALL32],0);198 POPFD199 return res;200}201 202U32 PCIReadU32(I64 bus,I64 dev,I64 fun,I64 rg)203{//Read U32 in PCI configspace at bus,dev,fun,reg.204 I64 res;205 PUSHFD206 CLI207 while (LBts(&sys_semas[SEMA_FAR_CALL32],0))208 Yield;209 c32_eax=0xB10A;210 c32_ebx=bus<<8+dev<<3+fun;211 c32_edi=rg;212 if (FarCall32(sys_pci_services))213 res=c32_ecx;214 else215 res=0xFFFFFFFF;216 LBtr(&sys_semas[SEMA_FAR_CALL32],0);217 POPFD218 return res;219}220 221U0 PCIWriteU8(I64 bus,I64 dev,I64 fun,I64 rg,I64 val)222{//Write U8 in PCI configspace at bus,dev,fun,reg.223 PUSHFD224 CLI225 while (LBts(&sys_semas[SEMA_FAR_CALL32],0))226 Yield;227 c32_eax=0xB10B;228 c32_ebx=bus<<8+dev<<3+fun;229 c32_edi=rg;230 c32_ecx=val;231 FarCall32(sys_pci_services);232 LBtr(&sys_semas[SEMA_FAR_CALL32],0);233 POPFD234}235 236U0 PCIWriteU16(I64 bus,I64 dev,I64 fun,I64 rg,I64 val)237{//Write U16 in PCI configspace at bus,dev,fun,reg.238 PUSHFD239 CLI240 while (LBts(&sys_semas[SEMA_FAR_CALL32],0))241 Yield;242 c32_eax=0xB10C;243 c32_ebx=bus<<8+dev<<3+fun;244 c32_edi=rg;245 c32_ecx=val;246 FarCall32(sys_pci_services);247 LBtr(&sys_semas[SEMA_FAR_CALL32],0);248 POPFD249}250 251U0 PCIWriteU32(I64 bus,I64 dev,I64 fun,I64 rg,I64 val)252{//Write U32 in PCI configspace at bus,dev,fun,reg.253 PUSHFD254 CLI255 while (LBts(&sys_semas[SEMA_FAR_CALL32],0))256 Yield;257 c32_eax=0xB10D;258 c32_ebx=bus<<8+dev<<3+fun;259 c32_edi=rg;260 c32_ecx=val;261 FarCall32(sys_pci_services);262 LBtr(&sys_semas[SEMA_FAR_CALL32],0);263 POPFD264}265 266I64 PCIClassFind(I64 class_code,I64 n)267{/*Find bus,dev,fun of Nth class_code dev.268 269class_code is low three bytes270n is index starting at zero271Return: -1 not found272else bus,dev,fun.273*/274 I64 res;275 PUSHFD276 CLI277 while (LBts(&sys_semas[SEMA_FAR_CALL32],0))278 Yield;279 c32_eax=0xB103;280 c32_esi=n;281 c32_ecx=class_code;282 if (FarCall32(sys_pci_services) && !c32_eax.u8[1])283 res=c32_ebx.u8[1]<<16+(c32_ebx&0xF8)<<5+c32_ebx&7;284 else285 res=-1;286 LBtr(&sys_semas[SEMA_FAR_CALL32],0);287 POPFD288 return res;289}290 291 