// File: joakimkistowski[P]amd-disable-c6/amd-disable-c6.cpp
// Function: write_msr(long, unsigned long, int)
unsigned int write_msr(long int msr_addr, uint64_t value, int cpu_id = -1) {
    if (cpu_id < 0) {
        unsigned int ret = 0;
        std::vector<int> ids;
        get_cpu_ids(ids);
        for (const int& id : ids) {
            if (id > 0) {
                ret = ret | write_msr(msr_addr, value, id);
            }
        }
        return ret;
    } else {
        std::string path = std::string("/dev/cpu/") + std::to_string(cpu_id) + std::string("/msr");
        FILE * f = fopen(path.c_str(), "w");
        if (!f) {
            std::cerr << "Failed writing of C6 state; msr module is not loaded in kernel" << std::endl;
            return 1;
        }
        int err = fseek (f, msr_addr, SEEK_SET);
        if (err) {
            std::cerr << "Failed writing of C6 state; error writing to msr" << std::endl;
            fclose(f);
            return 1;
        }
        fwrite(&value, 8, 1, f);
        fclose(f);
    }
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x170, %rsp            # imm = 0x170
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
jge 0x2e05
movl $0x0, -0x20(%rbp)
leaq -0x38(%rbp), %rdi
movq %rdi, -0x130(%rbp)
callq 0x4030
movq -0x130(%rbp), %rdi
callq 0x2900
jmp 0x2d45
leaq -0x38(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rdi
callq 0x4050
movq %rax, -0x58(%rbp)
movq -0x50(%rbp), %rdi
callq 0x4080
movq %rax, -0x60(%rbp)
leaq -0x58(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x40b0
testb $0x1, %al
jne 0x2d7a
jmp 0x2df1
leaq -0x58(%rbp), %rdi
callq 0x40f0
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
cmpl $0x0, (%rax)
jle 0x2de1
movl -0x20(%rbp), %eax
movl %eax, -0x138(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x68(%rbp), %rax
movl (%rax), %edx
callq 0x2d00
movl %eax, -0x134(%rbp)
jmp 0x2db4
movl -0x134(%rbp), %ecx
movl -0x138(%rbp), %eax
orl %ecx, %eax
movl %eax, -0x20(%rbp)
jmp 0x2de1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x4130
jmp 0x310d
jmp 0x2de3
leaq -0x58(%rbp), %rdi
callq 0x4110
jmp 0x2d67
movl -0x20(%rbp), %eax
movl %eax, -0x4(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x4130
jmp 0x3101
leaq -0xc9(%rbp), %rdi
movq %rdi, -0x140(%rbp)
callq 0x23a0
movq -0x140(%rbp), %rdx
leaq 0x3228(%rip), %rsi      # 0x604e
leaq -0xc8(%rbp), %rdi
callq 0x3ed0
jmp 0x2e34
movl -0x1c(%rbp), %esi
leaq -0xf0(%rbp), %rdi
callq 0x4260
jmp 0x2e45
leaq -0xa8(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
leaq -0xf0(%rbp), %rdx
callq 0x4190
jmp 0x2e61
leaq -0x111(%rbp), %rdi
movq %rdi, -0x148(%rbp)
callq 0x23a0
movq -0x148(%rbp), %rdx
leaq 0x31fe(%rip), %rsi      # 0x6080
leaq -0x110(%rbp), %rdi
callq 0x3ed0
jmp 0x2e90
leaq -0x88(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
leaq -0x110(%rbp), %rdx
callq 0x4190
jmp 0x2eac
leaq -0x110(%rbp), %rdi
callq 0x2428
leaq -0x111(%rbp), %rdi
callq 0x2210
leaq -0xa8(%rbp), %rdi
callq 0x2428
leaq -0xf0(%rbp), %rdi
callq 0x2428
leaq -0xc8(%rbp), %rdi
callq 0x2428
leaq -0xc9(%rbp), %rdi
callq 0x2210
leaq -0x88(%rbp), %rdi
callq 0x20c0
movq %rax, %rdi
leaq 0x317b(%rip), %rsi      # 0x6085
callq 0x2260
movq %rax, -0x150(%rbp)
jmp 0x2f18
movq -0x150(%rbp), %rax
movq %rax, -0x120(%rbp)
cmpq $0x0, -0x120(%rbp)
jne 0x3029
movq 0x60b5(%rip), %rdi      # 0x8ff0
leaq 0x3145(%rip), %rsi      # 0x6087
callq 0x21b0
movq %rax, -0x158(%rbp)
jmp 0x2f50
movq -0x158(%rbp), %rdi
movq 0x6052(%rip), %rsi      # 0x8fb0
callq 0x21f0
jmp 0x2f65
movl $0x1, -0x4(%rbp)
movl $0x1, -0x124(%rbp)
jmp 0x30de
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x2ffb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x2fef
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x2fe3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x2fcb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x110(%rbp), %rdi
callq 0x2428
leaq -0x111(%rbp), %rdi
callq 0x2210
leaq -0xa8(%rbp), %rdi
callq 0x2428
leaq -0xf0(%rbp), %rdi
callq 0x2428
leaq -0xc8(%rbp), %rdi
callq 0x2428
leaq -0xc9(%rbp), %rdi
callq 0x2210
jmp 0x310d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x88(%rbp), %rdi
callq 0x2428
jmp 0x310d
movq -0x120(%rbp), %rdi
movq -0x10(%rbp), %rsi
xorl %edx, %edx
callq 0x2240
movl %eax, -0x15c(%rbp)
jmp 0x3043
movl -0x15c(%rbp), %eax
movl %eax, -0x128(%rbp)
cmpl $0x0, -0x128(%rbp)
je 0x30aa
movq 0x5f91(%rip), %rdi      # 0x8ff0
leaq 0x3060(%rip), %rsi      # 0x60c6
callq 0x21b0
movq %rax, -0x168(%rbp)
jmp 0x3074
movq -0x168(%rbp), %rdi
movq 0x5f2e(%rip), %rsi      # 0x8fb0
callq 0x21f0
jmp 0x3089
movq -0x120(%rbp), %rdi
callq 0x21c0
jmp 0x3097
movl $0x1, -0x4(%rbp)
movl $0x1, -0x124(%rbp)
jmp 0x30de
movq -0x120(%rbp), %rcx
leaq -0x18(%rbp), %rdi
movl $0x8, %esi
movl $0x1, %edx
callq 0x23d0
jmp 0x30c6
movq -0x120(%rbp), %rdi
callq 0x21c0
jmp 0x30d4
movl $0x0, -0x124(%rbp)
leaq -0x88(%rbp), %rdi
callq 0x2428
movl -0x124(%rbp), %eax
testl %eax, %eax
je 0x30f8
jmp 0x30f6
jmp 0x3101
jmp 0x30fa
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x170, %rsp            # imm = 0x170
popq %rbp
retq
movq -0x40(%rbp), %rdi
callq 0x2390
nopw %cs:(%rax,%rax)