package net.katsuster.ememu.riscv;

import net.katsuster.ememu.generic.*;
import net.katsuster.ememu.riscv.core.*;

/**
 * Power Reset Clocking Interrupt (PRCI)
 *
 * 参考: SiFive FU540-C000 Manual: v1p0
 */
public class PRCI implements ParentCore {
    private RV64[] cores;
    private PRCI.PRCISlave slave;

    public static final int REG_HFXOSCCFG         = 0x0000;
    public static final int REG_COREPLLCFG0       = 0x0004;
    public static final int REG_DDRPLLCFG0        = 0x000c;
    public static final int REG_DDRPLLCFG1        = 0x0010;
    public static final int REG_GEMGXLPLLCFG0     = 0x001c;
    public static final int REG_GEMGXLPLLCFG1     = 0x0020;
    public static final int REG_CORECLKSEL        = 0x0024;
    public static final int REG_DEVICESRESETREG   = 0x0028;

    public static final int REG_UNDOCUMENTD0      = 0x002c;

    public PRCI(RV64[] c) {
        cores = c;
        slave = new PRCISlave();
    }

    @Override
    public SlaveCore64 getSlaveCore() {
        return slave;
    }

    class PRCISlave extends Controller32 {
        public PRCISlave() {
            addReg(REG_HFXOSCCFG,       "HFXOSCCFG", 0x00000000);
            addReg(REG_COREPLLCFG0,     "COREPLLCFG0", 0x00000000);
            addReg(REG_DDRPLLCFG0,      "DDRPLLCFG0", 0x00000000);
            addReg(REG_DDRPLLCFG1,      "DDRPLLCFG1", 0x00000000);
            addReg(REG_GEMGXLPLLCFG0,   "GEMGXLPLLCFG0", 0x00000000);
            addReg(REG_GEMGXLPLLCFG1,   "GEMGXLPLLCFG1", 0x00000000);
            addReg(REG_CORECLKSEL,      "CORECLKSEL", 0x00000000);
            addReg(REG_DEVICESRESETREG, "DEVICESRESETREG", 0x00000000);

            addReg(REG_UNDOCUMENTD0, "UNDOCUMENTED0", 0x00000000);
        }
        @Override
        public int readWord(BusMaster64 m, long addr) {
            int regaddr;
            int result;

            regaddr = (int) (addr & BitOp.getAddressMask(LEN_WORD_BITS));

            switch (regaddr) {
            default:
                result = super.readWord(m, regaddr);
                break;
            }

            return result;
        }

        @Override
        public void writeWord(BusMaster64 m, long addr, int data) {
            int regaddr;

            regaddr = (int) (addr & BitOp.getAddressMask(LEN_WORD_BITS));

            switch (regaddr) {
            case REG_UNDOCUMENTD0:
                System.out.printf("prci: UNDOCUMENTED0: %08x\n", data);
                break;
            default:
                super.writeWord(m, regaddr, data);
                break;
            }
        }
    }
}

@@ -422,16 +422,76 @@
 0x0004;%0A
+    public static final int REG_COREPLLCFG1       = 0x0008;%0A
     publ
@@ -1197,25 +1197,25 @@
 XOSCCFG%22, 0x
-0
+8
 0000000);%0A  
@@ -1258,32 +1258,100 @@
   %22COREPLLCFG0%22,
+ 0x030187c1);%0A            addReg(REG_COREPLLCFG1,     %22COREPLLCFG1%22,
  0x00000000);%0A  
@@ -1397,39 +1397,39 @@
 DDRPLLCFG0%22, 0x0
-0000000
+30187c1
 );%0A            a
@@ -1538,31 +1538,31 @@
 LLCFG0%22, 0x0
-0000000
+30187c1
 );%0A         
@@ -1817,33 +1817,33 @@
 TED0%22, 0x0000000
-0
+4
 );%0A        %7D%0A   
@@ -1831,32 +1831,33 @@
 004);%0A        %7D%0A
+%0A
         @Overrid
@@ -2062,32 +2062,223 @@
 tch (regaddr) %7B%0A
+            case REG_UNDOCUMENTD0:%0A                result = super.readWord(m, regaddr);%0A%0A                System.out.printf(%22prci: RD: UNDOCUMENTED0: %2508x%5Cn%22, result);%0A%0A                break;%0A
             defa
@@ -2704,16 +2704,20 @@
 f(%22prci:
+ WR:
  UNDOCUM
@@ -2732,32 +2732,83 @@
 %2508x%5Cn%22, data);%0A
+                super.writeWord(m, regaddr, data);%0A
                 

add initial register value of PRCI