On Sun, Sep 17, 2023 at 04:22:14PM +0200, Mark Kettenis wrote:
> > Date: Sun, 17 Sep 2023 12:40:29 +0200
> > From: "Peter J. Philipp" <p...@delphinusdns.org>
> 
> Sorry Peter,
> 
> But this doesn't make any sense to me.  Your C code is just as
> unreadable as the assembly code ;)
> 
> And your explanation doesn't make sense.  The code works fine on
> existing hardware supported by OpenBSD.  Your previous mails were also
> high on speculation and low on facts.
> 
> Cheers,
> 
> Mark

I took a break thought about what you said and bettered the C code.  I hope
it makes better sense?

Code after .signature.

Best Regards,
-peter


/*

     94         lla     s1, pagetable_l2
     95         srli    t4, s9, L2_SHIFT        
     96         li      t2, 512                
     97         add     t3, t4, t2
     98         li      t0, (PTE_KERN | PTE_X)
     99 1:
    100         slli    t2, t4, PTE_PPN1_S    
    101         or      t5, t0, t2
    102         sd      t5, (s1)             
    103         addi    s1, s1, PTE_SIZE
    104
    105         addi    t4, t4, 1
    106         bltu    t4, t3, 1b
    107

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define P_KERN  0x1     /* not real, for demonstration purposes only */
#define P_X     0x2     /* not real, for demonstration purposes only */

char *
binary(ulong t5)
{
        static char ret[1280];
        int i = 0;

        ret[0] = '\0';

        for (i = 53; i >= 0; i--) {
                switch (i) {
                case (53 - 26):
                        strlcat(ret,"", sizeof(ret));
                        break;
                case (53 - 26 - 9):
                        strlcat(ret,"", sizeof(ret));
                        break;
                case (53 - 26 - 9 - 9):
                        strlcat(ret,"", sizeof(ret));
                        break;
                default:
                        //strlcat(ret,"", sizeof(ret));
                        break;
                }

                if (t5 & (1UL << i)) {
                        strlcat(ret, "1", sizeof(ret));
                } else {
                        strlcat(ret, "0", sizeof(ret));
                }
        }
                
        return (&ret[0]);
}
        
/* 
 * from /usr/src/sys/arch/riscv64/include/pte.h -
 * PTE magic numbers sed'ed s/PTE_/P_/g 
 */
        
#define P_SIZE                  8               /* 8 bytes PTE size */
#define P_PPN1_S                19              /* explanation below */

/*
 * P_PPN1_S is a shift of bits from the LSb of the PTE leftwards to the 
 * respective level (given 0, 1, 2, 3), this is becuase the PTE looks like
 * this:
 *
 *                      Sv39 Page Table Entry
 * 63                                                              0
 * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
 * |N| rsvd|         PPN[2]          | PPN[1] |  PPN[0] | ptebits |
 * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 *         |            26           |  9     |   9     |   10
 *         |                         |        |         |
 *         |                         |        |         |
 *         |                         |        |         +--->    P_PPN0_S 10
 *         |                         |        |         
 *         |                         |        +----------->      P_PPN1_S 19
 *         |                         |        
 *         |                         +-------------------->      P_PPN2_S 28
 *         |                         
 *         +---------------------------------------------->      P_PPN3_S 37*
 *                                                              
 *   * In Sv39 this is really 26? which is 26 bits pages, or 67,108,864 pages
 *      or 64 Mega Pages (not to be confused with the Megapage ie, PPN[1]
 *      or 274877906944 bytes (big number)
 *                                   
 */

#define L2_SHIFT                21              /* 2 MiB == 21 bits == 2 ^ 21 */
#define PAGE_SHIFT              12              /* 4096 bytes */


int
main(int argc, char *argv[])
{
        u_long pagetable_l2 = 0x100c000UL;/* VA from readelf -a bsd  |\
                                                        grep pagetable_l2 */

        u_long physmem = 0x40200000UL >> ((argc > 1) ? PAGE_SHIFT : 0); /* PA 
in s9 */  
        u_long megapages = physmem >> L2_SHIFT; /* physmem base / 2 MiB */
        u_long slot = 512;                      /* slot # */
        u_long slot_limit = megapages + slot;
        u_long pte_bits = (P_KERN | P_X);       /* reg t0, spans 10b from LSb */
        u_long pte;                             /* register t5 */

        do {
                /* 100         slli    t2, t4, PTE_PPN1_S     */

                 slot = megapages << P_PPN1_S;


                /* 101         or      t5, t0, t2 */

                pte = pte_bits | slot;

                
                /* 102         sd      t5, (s1)             */


                printf("sd %08lX(%s) to %lX\n", pte, binary(pte), \
                        pagetable_l2);


                /* 103         addi    s1, s1, PTE_SIZE */


                pagetable_l2 += P_SIZE;


                /* 105         addi    t4, t4, 1 */

                megapages += 1;


                /* 106         bltu    t4, t3, 1b */

        } while (megapages < slot_limit);
        
        
        return 0;
}

Reply via email to