return -1 if invalid CSR, 0 if OK, 1 if the interpreter loop must be exited (e.g. XLEN was modified), 2 if TLBs have been flushed. */
| 879 | /* return -1 if invalid CSR, 0 if OK, 1 if the interpreter loop must be |
| 880 | exited (e.g. XLEN was modified), 2 if TLBs have been flushed. */ |
| 881 | static int csr_write(RISCVCPUState *s, uint32_t csr, target_ulong val) |
| 882 | { |
| 883 | target_ulong mask; |
| 884 | |
| 885 | #if defined(DUMP_CSR) |
| 886 | printf("csr_write: csr=0x%03x val=0x", csr); |
| 887 | print_target_ulong(val); |
| 888 | printf("\n"); |
| 889 | #endif |
| 890 | switch(csr) { |
| 891 | #if FLEN > 0 |
| 892 | case 0x001: /* fflags */ |
| 893 | s->fflags = val & 0x1f; |
| 894 | s->fs = 3; |
| 895 | break; |
| 896 | case 0x002: /* frm */ |
| 897 | set_frm(s, val & 7); |
| 898 | s->fs = 3; |
| 899 | break; |
| 900 | case 0x003: /* fcsr */ |
| 901 | set_frm(s, (val >> 5) & 7); |
| 902 | s->fflags = val & 0x1f; |
| 903 | s->fs = 3; |
| 904 | break; |
| 905 | #endif |
| 906 | case 0x100: /* sstatus */ |
| 907 | set_mstatus(s, (s->mstatus & ~SSTATUS_MASK) | (val & SSTATUS_MASK)); |
| 908 | break; |
| 909 | case 0x104: /* sie */ |
| 910 | mask = s->mideleg; |
| 911 | s->mie = (s->mie & ~mask) | (val & mask); |
| 912 | break; |
| 913 | case 0x105: |
| 914 | s->stvec = val & ~3; |
| 915 | break; |
| 916 | case 0x106: |
| 917 | s->scounteren = val & COUNTEREN_MASK; |
| 918 | break; |
| 919 | case 0x140: |
| 920 | s->sscratch = val; |
| 921 | break; |
| 922 | case 0x141: |
| 923 | s->sepc = val & ~1; |
| 924 | break; |
| 925 | case 0x142: |
| 926 | s->scause = val; |
| 927 | break; |
| 928 | case 0x143: |
| 929 | s->stval = val; |
| 930 | break; |
| 931 | case 0x144: /* sip */ |
| 932 | mask = s->mideleg; |
| 933 | s->mip = (s->mip & ~mask) | (val & mask); |
| 934 | break; |
| 935 | case 0x180: |
| 936 | /* no ASID implemented */ |
| 937 | #if MAX_XLEN == 32 |
| 938 | { |
no test coverage detected