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" <[email protected]>
>
> 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,"[32m", sizeof(ret));
break;
case (53 - 26 - 9):
strlcat(ret,"[34m", sizeof(ret));
break;
case (53 - 26 - 9 - 9):
strlcat(ret,"[35m", sizeof(ret));
break;
default:
//strlcat(ret,"[0m", 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[0m) 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;
}