On Tue, Sep 05, 2023 at 11:40:42PM +0200, Peter J. Philipp wrote: > Hi, > > I'm porting OpenBSD to the Mango Pi D1. Most of the work is done but now > is the time to try to get a RAMDISK kernel to boot. > > I'm having an issue with atomic_store_64() as shown here (line 1192): > > 1184 for (; va < DMAP_MAX_ADDRESS && pa < max_pa; > 1185 pa += L1_SIZE, va += L1_SIZE, l1_slot++) { > 1186 KASSERT(l1_slot < Ln_ENTRIES); > 1187 > 1188 /* gigapages */ > 1189 pn = (pa / PAGE_SIZE); > 1190 entry = PTE_KERN; > 1191 entry |= (pn << PTE_PPN0_S); > 1192 atomic_store_64(&l1[l1_slot], entry); > 1193 } > > The D1 seems to hang on this call. To me that seems like the store hangs that > I did on powerpc64 when memory was not aligned. When I replaced the > AMO instruction with a simple C replacement it worked. So I wonder if the > following is correct or not: > > entry = _ALIGN(PTE_KERN); > > I looked at riscv-privileged-202111203.pdf (page 79) which is for Sv32 and > a few pages down is the Sv39 (page 84). But I can't make sense of it. And > my Mona Lisa book that I have from Waterman mentions on page 101: > > ''Misaligned address exceptions occur when the effective address isn't > divisible > by the access size - for example, amoadd.w with an address of 0x12.'' > > I don't think in the bootstrapping of pmap that traps are turned on yet, > but I could be mistaken, hence the hang.
There is something weird which I can't figure out, this document is golden to find the truth: https://github.com/riscv/riscv-isa-manual/releases/download/Priv-v1.12/riscv-privileged-20211203.pdf OK on page 79 is the Sv32 (32-bit specification), it is kinda irrelevant for us but there is something bothering me, and we must see into this so that we can talk about Sv39 (64-bit) which is on page 84, and Sv48 which is on page 86. Sv32: on page 80, figure 4.17 is the 32-bit physical address translation (based on satp register's MODE) and PPN0 is 10 bits here. PPN1 is 12 bits. PPN is the physical page number. And the 0 and 1 is the levels of what sort of pages these are. 4096 byte size is level 0, and level 1 is 4MB (megapages) size. PTESIZE=4 Sv39: on page 85, figure 4.20, is the 64-bit (Sv39) physical address translation based on the satp register which is 64 bits. PPN0 is 9 bits here, PPN1 is 9 bits and PPN2 is 26 bits. These three levels represent 4096 byte physical page numbers (level 0), 2 MB megapages PPN's (level 1) and 1 GB gigapages PPN's. "each of which must be virtually and physically aligned to a boundary equal to its size. A page-fault exception is raised if the physical address is insufficently aligned". PTESIZE=8 Sv48: on page 86, figure 4.23, is a 64-bit (Sv48) physical address translation based on the satp register again which is 64 bits. They have 4 levels of PPN numbers; level 0 pages (9 bits), level 1 megapages (9 bits), level 2 gigapages (9 bits) and also introduce 512 GB terapages on level 3 (17 bits). PTESIZE=8 OK now that I have repeated the document I have 3 questions: 1. AFAIK, we ONLY support Sv39 right now, is this true? 2. From /usr/src/sys/arch/riscv64/include/pte.h: #define PTE_PPN0_S 10 This is the PPN shift value...why is it 10 and not 9? We're using Sv39. If this is wrong then PTE_PPN[123] also have to be adjusted. 3. Why are we talking about 4 levels of PPN's when there is only 3 levels in the Sv39 definition? I put some debugging into my kernel this morning and added a printf in pmap's pmap_bootstrap_dmap() and had it just before the atomic function: >> OpenBSD/riscv64 BOOTRISCV64 1.5 boot> boot cannot open sd0a:/etc/random.seed: No such file or directory booting sd0a:/bsd: 2152904+693716+8907000+538152 [181604+122+283464+186377]=0xfa1420 bootargs: aligned_entry=10001000,pn=40000,ae%pn=1000,&l1[l1s]=ffffffc00100ba00 This is what it showed me. In my tests instead of _ALIGN()'ing PTE_KERN I round_page() the entry value to make it 4096 page aligned (10001000), I also show the physmem in page numbers 0x40000 which is 262144 pages for 1 GB RAM. aligned_entry % pn == 0x1000, which didn't fit exactly into this. and finally &l1[l1_slot] which gave this odd looking number: 0xffffffc00100ba00 This is not a page aligned offset, on any physical page number. L1_slot I think was 320 from earlier debugs and I left it alone in my tests. Let's see, here it is: before atomic store l1=ffffffc00100a000 l1_slot=320,[ffffffc00100aa00], entry = 100000c7 So I'm wondering about these misalignments and the questions above. > If you have another idea why I get these let me know, I'm going to bed now > and won't be up until 6AM or later tomorrow. I'm letting my kernel compile > on the slow QEMU host overnight. Sorry about this, tb@, I'll try to refrain from mentioning my bed times. Best Regards, -peter -- Over thirty years experience on Unix-like Operating Systems starting with QNX.