smp boots!
This commit is contained in:
parent
079c3308b8
commit
b2dc154433
440
src/.gdb_history
440
src/.gdb_history
@ -1,256 +1,256 @@
|
||||
c
|
||||
info threads
|
||||
quit
|
||||
c
|
||||
info threads
|
||||
thread 1
|
||||
next
|
||||
thread 1
|
||||
step
|
||||
c
|
||||
print cores
|
||||
print cores_active
|
||||
info threads
|
||||
c
|
||||
info threads
|
||||
print core_stacks
|
||||
print core_stacks[0]
|
||||
print core_stacks[1]
|
||||
print core_stacks[2]
|
||||
print core_stacks[3]
|
||||
quit
|
||||
c
|
||||
info threads
|
||||
c
|
||||
info threads
|
||||
quit
|
||||
b smp_boot
|
||||
c
|
||||
qit
|
||||
quit
|
||||
b smp.c:59
|
||||
c
|
||||
next
|
||||
info threads
|
||||
next
|
||||
info threads
|
||||
next
|
||||
info threads
|
||||
info threads
|
||||
info threads
|
||||
quit
|
||||
b smp.c:65
|
||||
c
|
||||
next
|
||||
info threads
|
||||
info thread 2
|
||||
quit
|
||||
b timer.c:57
|
||||
c
|
||||
quit
|
||||
b timer.c:57
|
||||
hb debug
|
||||
c
|
||||
c
|
||||
next
|
||||
info reg rax
|
||||
thread 1
|
||||
thread 2
|
||||
info reg rax
|
||||
print smp_bootstrap_stackarray
|
||||
print *smp_bootstrap_stackarray
|
||||
print/x *smp_bootstrap_stackarray
|
||||
inf ore g rax
|
||||
print smp_bootstrap_array
|
||||
quit
|
||||
hb debug
|
||||
c
|
||||
c
|
||||
quit
|
||||
b smp.c:57
|
||||
hb debug
|
||||
c
|
||||
print *(uint32_t *)&icr
|
||||
print/x *(uint32_t *)&icr
|
||||
info threads
|
||||
next
|
||||
info threads
|
||||
next
|
||||
info threads
|
||||
next
|
||||
info threads
|
||||
next
|
||||
info threads
|
||||
next
|
||||
info threads
|
||||
next
|
||||
info threads
|
||||
print/x *(uint32_t *)&icr
|
||||
pirnt (void *)0x8000
|
||||
prit (void *)0x8000
|
||||
print (void *)0x8000
|
||||
print *(void *)0x8000
|
||||
print __load_start_smp_bootloader
|
||||
print &__load_start_smp_bootloader
|
||||
print (void *)&__load_start_smp_bootloader
|
||||
print (void *)&__load_stop_smp_bootloader
|
||||
c
|
||||
nexti
|
||||
info reg ebx
|
||||
info reg ebx
|
||||
quit
|
||||
print &__load_start_smp_bootloader
|
||||
print &__load_stop_smp_bootloader
|
||||
print &__load_stop_smp_bootloader
|
||||
print smp_bootstrap
|
||||
print smp_bootloader
|
||||
print &__load_stop_smp_bootloader
|
||||
print __load_stop_smp_bootloader
|
||||
print &__load_stop_smp_bootloader
|
||||
print smp_bootstrap_corecount
|
||||
b smp_trampoline
|
||||
hb smp_trampoline
|
||||
hb debug
|
||||
c
|
||||
d
|
||||
d
|
||||
hb smp_trampoline
|
||||
c
|
||||
info reg rip
|
||||
quit
|
||||
hb debug
|
||||
c
|
||||
c
|
||||
stepi
|
||||
info reg ebx
|
||||
stepi
|
||||
stepi
|
||||
info reg rsp
|
||||
stepi
|
||||
info reg esp
|
||||
info reg rsp
|
||||
x rbx
|
||||
info reg rbx
|
||||
print smp_bootstrap_stackarray
|
||||
print/x *smp_bootstrap_stackarray
|
||||
info reg ebx
|
||||
quit
|
||||
quit
|
||||
stepi
|
||||
info reg cl
|
||||
info reg ecx
|
||||
quit
|
||||
next
|
||||
quit
|
||||
nexti
|
||||
info reg ecx
|
||||
stepi
|
||||
info reg ebx
|
||||
quit
|
||||
c
|
||||
quit
|
||||
stepi
|
||||
info reg ebx
|
||||
stepi
|
||||
info reg bl
|
||||
print smp_bootstrap_bsp
|
||||
info reg bl
|
||||
stepi
|
||||
info reg bl
|
||||
info reg ebx
|
||||
x 0x80f0
|
||||
print (uint64_t *)0x80f0
|
||||
print (uint64_t*)0x80f0
|
||||
x 0x80f9
|
||||
stepi
|
||||
stepi
|
||||
info reg rsp
|
||||
print smp_bootstrap_stackarray
|
||||
print/x *smp_bootstrap_stackarray
|
||||
quit
|
||||
info reg rax
|
||||
info reg rax
|
||||
x 0xbffde058
|
||||
print smp_bootstrap_bsp
|
||||
print &smp_bootstrap_bsp
|
||||
print smp_bootstrap_bsp
|
||||
x 0x80f1
|
||||
print (uint64_t)*0x80f1
|
||||
x smp_bootstrap_bsp
|
||||
smp_bootstrap_bsp
|
||||
print smp_bootstrap_bsp
|
||||
smp_bootstrap_stackarray
|
||||
print smp_bootstrap_stackarray
|
||||
print *smp_bootstrap_stackarray
|
||||
print smp_bootstrap_stackarray[0]
|
||||
print/x smp_bootstrap_stackarray[0]
|
||||
print/x smp_bootstrap_stackarray[1]
|
||||
print/x smp_bootstrap_stackarray[0]
|
||||
info reg rax
|
||||
print smp_bootstrap_stackarray
|
||||
quit
|
||||
info reg rax
|
||||
quit
|
||||
next
|
||||
stepi
|
||||
quit
|
||||
c
|
||||
quit
|
||||
c
|
||||
stepi
|
||||
quit
|
||||
hb smp_trampoline
|
||||
c
|
||||
next
|
||||
hb debug
|
||||
c
|
||||
quit
|
||||
c
|
||||
quit
|
||||
hb smp_trampoline
|
||||
c
|
||||
info threads
|
||||
hexdump 0
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
cc
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
d
|
||||
c
|
||||
quit
|
||||
b smp_trampoline
|
||||
c
|
||||
hb smp_trampoline
|
||||
d 2
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
quit
|
||||
c
|
||||
info threads
|
||||
stepi
|
||||
quit
|
||||
c
|
||||
info threads
|
||||
quit
|
||||
info threads
|
||||
next
|
||||
next
|
||||
print 0x8000 / 0x1000
|
||||
next
|
||||
quit
|
||||
quit
|
||||
next
|
||||
info threads
|
||||
next
|
||||
info threads
|
||||
next
|
||||
info threads
|
||||
quit
|
||||
next
|
||||
info threads
|
||||
next
|
||||
info threads
|
||||
next
|
||||
info threads
|
||||
next
|
||||
info threads
|
||||
next
|
||||
info threads
|
||||
next
|
||||
info threads
|
||||
quit
|
||||
hb 0
|
||||
c
|
||||
quit
|
||||
next
|
||||
next
|
||||
next
|
||||
print icr
|
||||
next
|
||||
next
|
||||
info threads
|
||||
quit
|
||||
next
|
||||
info threads
|
||||
next
|
||||
info threads
|
||||
next
|
||||
info threads
|
||||
next
|
||||
info threads
|
||||
quit
|
||||
b smp.c:60
|
||||
c
|
||||
next
|
||||
info threads
|
||||
next
|
||||
info threads
|
||||
info reg rsp
|
||||
thread 2
|
||||
context
|
||||
quit
|
||||
quit
|
||||
b memcpy
|
||||
c
|
||||
print dest
|
||||
x 0xffff800000008000
|
||||
print 0xffff800000008000
|
||||
print/x 0xffff800000008000
|
||||
print n
|
||||
b 54
|
||||
info reg cl
|
||||
info reg ecx
|
||||
quit
|
||||
c
|
||||
next
|
||||
info reg
|
||||
quit
|
||||
info reg rax
|
||||
c
|
||||
info reg rax
|
||||
stepi
|
||||
info rax
|
||||
inf oreg rax
|
||||
info reg rax
|
||||
info reg rbx
|
||||
inf reg rdi
|
||||
x/i 0xffff800000000000
|
||||
x/i 0xffff800000008000
|
||||
smp_trampoline
|
||||
hexdump 0xffff800000008000
|
||||
x 0xffff8000bffde058
|
||||
x *0xffff8000bffde058
|
||||
print *0xffff8000bffde058
|
||||
print/x *0xffff8000bffde058
|
||||
print/x (uint64_t)*0xffff8000bffde058
|
||||
print/x (uint64_t)0xffff8000bffde058
|
||||
print/x (uint64_t)*0xffff8000bffde058
|
||||
print/x (uint64_t)0xffff8000bffde058
|
||||
print/x (uint64_t)0xffff8000bffde058[1]
|
||||
print ((uint64_t)0xffff8000bffde058)[1]
|
||||
print ((uint64_t *)0xffff8000bffde058)[1]
|
||||
print ((uint64_t *)0xffff8000bffde058)[0]
|
||||
print ((uint64_t *)0xffff8000bffde058)[1]
|
||||
print/x ((uint64_t *)0xffff8000bffde058)[1]
|
||||
quit
|
||||
b memcpy
|
||||
c
|
||||
print dest
|
||||
hexdump 0xffff800000008000
|
||||
b 64
|
||||
nexti
|
||||
quit
|
||||
c
|
||||
stepi
|
||||
stepi
|
||||
info thread 0
|
||||
thread 1
|
||||
c
|
||||
hexdump 0xffff800000008000
|
||||
print __load_start_smp_bootloader
|
||||
hexdump 0xffff800000000800
|
||||
quit
|
||||
info reg rsp
|
||||
next
|
||||
print cores_active
|
||||
print cores.corecount
|
||||
next
|
||||
print cores.corecount
|
||||
print cores_active
|
||||
next
|
||||
c
|
||||
print cores_active
|
||||
thread 0
|
||||
print cores_active
|
||||
thread 1
|
||||
print cores_active
|
||||
quit
|
||||
c
|
||||
stepi
|
||||
info reg rax
|
||||
thread 0
|
||||
thread 2
|
||||
print cores_active
|
||||
context
|
||||
thread 1
|
||||
next
|
||||
c
|
||||
print cores_active
|
||||
print &cores_active
|
||||
thread 2
|
||||
info reg rax
|
||||
info reg rax
|
||||
x 0x1000bf
|
||||
quit
|
||||
c
|
||||
print smp_bootstrap_stackarray
|
||||
print smp_bootstrap_corecount
|
||||
print smp_bootstrap_bsp
|
||||
quit
|
||||
c
|
||||
x smp_bootstrap_bsp
|
||||
next
|
||||
print smp_bootstrap_bsp
|
||||
print smp_bootstrap_stackarray
|
||||
print smp_bootstrap_bsp
|
||||
print smp_bootstrap_bsp
|
||||
info reg rax
|
||||
x smp_bootstrap_corecount
|
||||
print smp_bootstrap_corecount
|
||||
quit
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
quit
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
quit
|
||||
b panic
|
||||
c
|
||||
thread
|
||||
threads
|
||||
info thread
|
||||
thread 2
|
||||
thread 3
|
||||
thread 4
|
||||
quit
|
||||
c
|
||||
c
|
||||
c
|
||||
c
|
||||
quit
|
||||
|
@ -116,5 +116,4 @@ jmp $
|
||||
%include "bootloader/cpu_check.asm"
|
||||
%include "bootloader/video.asm"
|
||||
%include "bootloader/enter_kernel.asm"
|
||||
|
||||
times 2048 - ($ - $$) db 0
|
||||
|
@ -1,5 +1,6 @@
|
||||
target remote localhost:1234
|
||||
symbol-file debug/debug_syms.o
|
||||
hb debug
|
||||
hb smp_boot
|
||||
|
||||
|
||||
|
@ -9,5 +9,7 @@
|
||||
|
||||
#define DEV_EMAIL "brett_weiland@bpcspace.com"
|
||||
|
||||
void multicore_main();
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -18,6 +18,7 @@ void pfree(void *addr, size_t size);
|
||||
void debug_pmap();
|
||||
void get_mem_capabilities();
|
||||
void ram_stresser();
|
||||
void fix_stack();
|
||||
|
||||
|
||||
#endif
|
||||
|
BIN
src/indigo_os
BIN
src/indigo_os
Binary file not shown.
@ -20,7 +20,10 @@
|
||||
#include <testmalloc.h>
|
||||
|
||||
|
||||
|
||||
void multicore_main() {
|
||||
printf("\nKernal started\n");
|
||||
asm("cli\nhlt");
|
||||
}
|
||||
|
||||
void main() {
|
||||
#ifndef SCREEN_OUTPUT
|
||||
@ -28,7 +31,6 @@ void main() {
|
||||
#endif
|
||||
get_mem_capabilities();
|
||||
init_pmap(map_complete_physical());
|
||||
unmap_lowmem();
|
||||
|
||||
|
||||
find_root_sdp();
|
||||
@ -40,6 +42,8 @@ void main() {
|
||||
randinit();
|
||||
|
||||
smp_boot();
|
||||
fix_stack();
|
||||
unmap_lowmem();
|
||||
|
||||
PANIC(KERNEL_PANIC_KERNEL_RETURNED);
|
||||
}
|
||||
|
@ -77,8 +77,7 @@ void get_mem_capabilities() {
|
||||
NX_capable = (edx >> 20) & 1;
|
||||
}
|
||||
|
||||
|
||||
void unmap_lowmem() {
|
||||
void fix_stack() {
|
||||
struct stack_frame *frame;
|
||||
|
||||
asm("addq rsp, %0\n"
|
||||
@ -92,7 +91,10 @@ void unmap_lowmem() {
|
||||
frame->next = PHYS_TO_VIRT((void *)frame->next);
|
||||
frame = frame->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void unmap_lowmem() {
|
||||
//[future]
|
||||
//eventually, you should use the function that unmaps pages when you write it
|
||||
page_table *entry = (page_table *)PAGEMAP_LOCATION;
|
||||
|
@ -1,9 +1,12 @@
|
||||
#include <kernel.h>
|
||||
#include <printf.h>
|
||||
#include <madt.h>
|
||||
#include <timer.h>
|
||||
#include <cpuid.h>
|
||||
#include <int.h>
|
||||
#include <libc.h>
|
||||
#include <paging.h>
|
||||
#include <heap.h>
|
||||
|
||||
#define LAPIC_ICR_LOW 192
|
||||
#define LAPIC_ICR_HIGH 196
|
||||
@ -11,6 +14,8 @@
|
||||
extern lapic_t lapic;
|
||||
extern char __load_start_smp_bootloader, __load_stop_smp_bootloader;
|
||||
extern uint8_t *smp_bootstrap_corecount;
|
||||
extern uint8_t smp_bootstrap_bsp;
|
||||
extern uint64_t *smp_bootstrap_stackarray;
|
||||
|
||||
struct icr_reg {
|
||||
uint8_t vector;
|
||||
@ -37,19 +42,24 @@ static inline void write_icr(uint8_t dest, uint32_t message) {
|
||||
}
|
||||
|
||||
void smp_boot() {
|
||||
uint8_t cores_active = 0; //TODO change in asm
|
||||
uint8_t cores_active = 1; //TODO change in asm
|
||||
struct cores_info cores;
|
||||
unsigned int ci;
|
||||
|
||||
struct icr_reg icr;
|
||||
get_coreinfo(&cores);
|
||||
bzero(&icr, sizeof(icr));
|
||||
|
||||
void **core_stacks = malloc(sizeof(void *) * (cores.corecount - 1));
|
||||
for(unsigned int s = 0; s < (cores.corecount - 1); s++) {
|
||||
core_stacks[s] = palloc(0x1000);
|
||||
}
|
||||
|
||||
memcpy(PHYS_TO_VIRT((void *)0x8000), PHYS_TO_VIRT(&__load_start_smp_bootloader),
|
||||
&__load_stop_smp_bootloader - &__load_start_smp_bootloader);
|
||||
*(uint8_t **)PHYS_TO_VIRT(&smp_bootstrap_corecount) = &cores_active;
|
||||
smp_bootstrap_corecount = &cores_active;
|
||||
smp_bootstrap_bsp = cores.bsp;
|
||||
smp_bootstrap_stackarray = (uint64_t)core_stacks;
|
||||
|
||||
|
||||
get_coreinfo(&cores);
|
||||
|
||||
icr.deliv_mode = 0b101;
|
||||
icr.dest_shorthand = 0b11;
|
||||
@ -61,20 +71,13 @@ void smp_boot() {
|
||||
icr.vector = 8;
|
||||
write_icr(0, *(uint32_t *)&icr);
|
||||
usleep(200);
|
||||
write_icr(0, *(uint32_t *)&icr);
|
||||
|
||||
/**
|
||||
if(cores_active != cores.corecount) write_icr(0, *(uint32_t *)&icr);
|
||||
usleep(200);
|
||||
if(cores_active != cores.corecount) {
|
||||
write_icr(0, *(uint32_t *)&icr);
|
||||
usleep(200);
|
||||
printf("NOT ALL CORES ONLINE\n");
|
||||
asm("cli\nhlt");
|
||||
}
|
||||
**/
|
||||
/**
|
||||
for(ci = 0; ci < cores.corecount; ci++) {
|
||||
if(ci == cores.bsp) continue;
|
||||
//send init sipi
|
||||
write_icr(ci, *(uint32_t *)&icr);
|
||||
else {
|
||||
printf("%i!!!!!!\n", cores_active);
|
||||
}
|
||||
**/
|
||||
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
global smp_bootstrap_corecount;
|
||||
global smp_bootstrap_stackarray
|
||||
global smp_bootstrap_bsp
|
||||
global smp_bootstrap_corecount
|
||||
|
||||
extern multicore_main
|
||||
|
||||
[bits 16]
|
||||
smp_trampoline:
|
||||
cli
|
||||
hlt
|
||||
hlt
|
||||
|
||||
xor ax, ax
|
||||
mov ds, ax
|
||||
@ -50,7 +52,7 @@ SMP_PROTECTED_DATA_SEGMENT equ .gdt_data_p - .gdt_start_p
|
||||
|
||||
;________________________________________________________________________________________
|
||||
|
||||
.smp_protected
|
||||
.smp_protected:
|
||||
|
||||
[bits 32]
|
||||
mov ax, SMP_PROTECTED_DATA_SEGMENT
|
||||
@ -60,6 +62,9 @@ mov es, ax
|
||||
mov fs, ax
|
||||
mov gs, ax
|
||||
|
||||
lgdt [.gdt_descriptor_l]
|
||||
|
||||
|
||||
mov eax, 0x10000 ;TODO clarify _why_ this is a thing
|
||||
mov cr3, eax
|
||||
|
||||
@ -82,12 +87,14 @@ or eax, 1 << 8 | 1 << 11
|
||||
or eax, edx
|
||||
wrmsr
|
||||
|
||||
|
||||
;enable paging
|
||||
mov eax, cr0
|
||||
or eax, 1 << 31 | 1 << 0;
|
||||
and ax, ~(1 << 2)
|
||||
mov cr0, eax
|
||||
|
||||
|
||||
jmp SMP_LONG_CODE_SEGMENT:.counter
|
||||
|
||||
;________________________________________________________________________________________
|
||||
@ -123,7 +130,7 @@ db 0
|
||||
.gdt_end_l: ; later calculates offset in defs below
|
||||
|
||||
|
||||
.descriptor_l:
|
||||
.gdt_descriptor_l:
|
||||
dw .gdt_end_l - .gdt_start_l - 1
|
||||
dq .gdt_start_l
|
||||
|
||||
@ -131,10 +138,27 @@ SMP_LONG_CODE_SEGMENT equ .gdt_code_l - .gdt_start_l
|
||||
SMP_LONG_DATA_SEGMENT equ .gdt_data_l - .gdt_start_l
|
||||
|
||||
.counter:
|
||||
mov rax, [smp_bootstrap_corecount]
|
||||
inc QWORD [rax]
|
||||
cli
|
||||
hlt
|
||||
;TODO set up stack; enter kernel
|
||||
mov eax, 1
|
||||
cpuid
|
||||
shr ebx, 24
|
||||
cmp bl, BYTE [smp_bootstrap_bsp]
|
||||
jl .apic_below_bsp
|
||||
sub bl, 1
|
||||
|
||||
.apic_below_bsp:
|
||||
|
||||
mov rax, QWORD [smp_bootstrap_stackarray]
|
||||
debug:
|
||||
mov rsp, QWORD [rax + rbx * 8]
|
||||
|
||||
mov rax, [smp_bootstrap_corecount]
|
||||
inc BYTE [rax]
|
||||
|
||||
mov rax, multicore_main
|
||||
jmp rax
|
||||
|
||||
align 8
|
||||
smp_bootstrap_stackarray: dq 0
|
||||
smp_bootstrap_bsp: db 0
|
||||
smp_bootstrap_corecount: db 0
|
||||
times 512 - ($ - $$) db 0
|
||||
|
16
src/link.ld
16
src/link.ld
@ -11,23 +11,23 @@ SECTIONS
|
||||
bootloader.o(.text)
|
||||
}
|
||||
smp_bootloader 0x8000 :
|
||||
AT(SIZEOF(bootloader))
|
||||
AT(0 + SIZEOF(bootloader))
|
||||
{
|
||||
smp_trampoline.o(.text)
|
||||
}
|
||||
kernel _kernel_s1_loc :
|
||||
AT (SIZEOF(bootloader))
|
||||
AT (0 + SIZEOF(smp_bootloader) + SIZEOF(bootloader))
|
||||
{
|
||||
EXCLUDE_FILE (*bootloader.o) *(.text .data .bss .rodata .comment .eh_frame)
|
||||
EXCLUDE_FILE (*bootloader.o *smp_trampoline.o) *(.text .data .bss .rodata .comment .eh_frame)
|
||||
}
|
||||
}
|
||||
|
||||
_kernel_sector_size = ((SIZEOF(kernel) + SIZEOF(smp_bootloader) + 511) / 512);
|
||||
_kernel_page_size = ((SIZEOF(kernel) + SIZEOF(smp_bootloader) + 0xfff) / 0x1000);
|
||||
_bootloader_stage1_size = (SIZEOF(bootloader) + 511) / 512;
|
||||
_kernel_sector_size = ((SIZEOF(kernel) + 511) / 512);
|
||||
_kernel_page_size = ((SIZEOF(kernel) + 0xfff) / 0x1000);
|
||||
_bootloader_stage1_size = (SIZEOF(bootloader) + SIZEOF(smp_bootloader) + 511) / 512;
|
||||
|
||||
__load_start_smp_bootloader = LOADADDR(smp_bootloader);
|
||||
__load_stop_smp_bootloader = LOADADDR(smp_bootloader) + SIZEOF(smp_bootloader);
|
||||
__load_start_smp_bootloader = LOADADDR(smp_bootloader) + 0x7c00;
|
||||
__load_stop_smp_bootloader = LOADADDR(smp_bootloader) + SIZEOF(smp_bootloader) + 0x7c00;
|
||||
|
||||
_kernel_stack_loc = (0x100000 + (_kernel_page_size * 0x1000) + 0x2000) - 8;
|
||||
_kernel_shared_zone_begin = 0x100000 + (_kernel_page_size * 0x1000) + 0x2000;
|
||||
|
Loading…
x
Reference in New Issue
Block a user