Port-amiga archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Weird calculation for kernel L2 segment table



sys/arch/amiga/amiga/amiga_init.c (and recently sync'ed atari_init.c)
has the following calculations to get the level2 segment table
for the kernel Sysptmap:

---
                /*
                 * Kernel segment table at end of next level 2 table
                 */
                /* XXX fix calculations XXX */
                i = ((((ptsize >> PGSHIFT) + 3) & -2) - 1) * (NPTEPG / 
SG4_LEV3SIZE);
                sg = &((st_entry_t *)(RELOC(Sysseg_pa, u_int)))[SG4_LEV1SIZE + 
i];
                esg = &sg[NPTEPG / SG4_LEV3SIZE];
                sg_proto = Sysptmap_pa | SG_U | SG_RW | SG_V;
                while (sg < esg) {
                        *sg++ = sg_proto;
                        sg_proto += (SG4_LEV3SIZE * sizeof (st_entry_t));
                }
---

I think this could be rewritten more meaningfully as following:

---
                nl2desc = (ptsize >> PGSHIFT) * (NPTEPG / SG4_LEV3SIZE);
        :
                nl1desc = roundup(nl2desc, SG4_LEV2SIZE) / SG4_LEV2SIZE;
        :
                /*
                 * Kernel segment table at end of next level 2 table
                 */
                i = SG4_LEV1SIZE + (nl1desc * SG4_LEV2SIZE);
                sg = (st_entry_t *)RELOC(Sysseg_pa, u_int);
                sg = &sg[i + SG4_LEV2SIZE - (NPTEPG / SG4_LEV3SIZE)];
                esg = &sg[NPTEPG / SG4_LEV3SIZE];
        :
---

With a quick test program, both offset values against Sysseg_pa
look identical.

How about this patch? Comments?

---
Index: amiga/amiga/amiga_init.c
===================================================================
RCS file: /cvsroot/src/sys/arch/amiga/amiga/amiga_init.c,v
retrieving revision 1.103
diff -u -r1.103 amiga_init.c
--- amiga/amiga/amiga_init.c    31 Dec 2008 19:54:40 -0000      1.103
+++ amiga/amiga/amiga_init.c    2 Jan 2009 04:44:43 -0000
@@ -218,6 +218,9 @@
        register pt_entry_t pg_proto, *pg, *epg;
        vaddr_t end_loaded;
        u_int ncd, i;
+#if defined(M68040) || defined(M68060)
+       u_int nl1desc, nl2desc;
+#endif
        vaddr_t kva;
        struct boot_memlist *ml;
 
@@ -432,9 +435,10 @@
                 * pages of PTEs.  Note that we set the "used" bit
                 * now to save the HW the expense of doing it.
                 */
-               i = (ptsize >> PGSHIFT) * (NPTEPG / SG4_LEV3SIZE);
-               sg = &((st_entry_t *)(RELOC(Sysseg_pa, u_int)))[SG4_LEV1SIZE];
-               esg = &sg[i];
+               nl2desc = (ptsize >> PGSHIFT) * (NPTEPG / SG4_LEV3SIZE);
+               sg = (st_entry_t *)RELOC(Sysseg_pa, u_int);
+               sg = &sg[SG4_LEV1SIZE];
+               esg = &sg[nl2desc];
                sg_proto = ptpa | SG_U | SG_RW | SG_V;
                while (sg < esg) {
                        *sg++ = sg_proto;
@@ -443,15 +447,13 @@
 
                /*
                 * Initialize level 1 descriptors.  We need:
-                *      roundup(num, SG4_LEV2SIZE) / SG4_LEVEL2SIZE
-                * level 1 descriptors to map the 'num' level 2's.
+                *      roundup(nl2desc, SG4_LEV2SIZE) / SG4_LEVEL2SIZE
+                * level 1 descriptors to map the 'nl2desc' level 2's.
                 */
-               i = roundup(i, SG4_LEV2SIZE) / SG4_LEV2SIZE;
+               nl1desc = roundup(nl2desc, SG4_LEV2SIZE) / SG4_LEV2SIZE;
                /* Include additional level 2 table for Sysmap in protostfree */
-               RELOC(protostfree, u_int) =
-                   (-1 << (i + 2)) /* & ~(-1 << MAXKL2SIZE) */;
                sg = (st_entry_t *)RELOC(Sysseg_pa, u_int);
-               esg = &sg[i];
+               esg = &sg[nl1desc];
                sg_proto = (paddr_t)&sg[SG4_LEV1SIZE] | SG_U | SG_RW | SG_V;
                while (sg < esg) {
                        *sg++ = sg_proto;
@@ -466,15 +468,17 @@
                /*
                 * Kernel segment table at end of next level 2 table
                 */
-               /* XXX fix calculations XXX */
-               i = ((((ptsize >> PGSHIFT) + 3) & -2) - 1) * (NPTEPG / 
SG4_LEV3SIZE);
-               sg = &((st_entry_t *)(RELOC(Sysseg_pa, u_int)))[SG4_LEV1SIZE + 
i];
+               i = SG4_LEV1SIZE + (nl1desc * SG4_LEV2SIZE);
+               sg = (st_entry_t *)RELOC(Sysseg_pa, u_int);
+               sg = &sg[i + SG4_LEV2SIZE - (NPTEPG / SG4_LEV3SIZE)];
                esg = &sg[NPTEPG / SG4_LEV3SIZE];
                sg_proto = Sysptmap_pa | SG_U | SG_RW | SG_V;
                while (sg < esg) {
                        *sg++ = sg_proto;
                        sg_proto += (SG4_LEV3SIZE * sizeof (st_entry_t));
                }
+               RELOC(protostfree, u_int) =
+                   (-1 << (1 + nl1desc + 1)) /* & ~(-1 << MAXKL2SIZE) */;
 
                /*
                 * Initialize Sysptmap
Index: atari/atari/atari_init.c
===================================================================
RCS file: /cvsroot/src/sys/arch/atari/atari/atari_init.c,v
retrieving revision 1.70
diff -u -r1.70 atari_init.c
--- atari/atari/atari_init.c    2 Jan 2009 04:38:09 -0000       1.70
+++ atari/atari/atari_init.c    2 Jan 2009 04:44:43 -0000
@@ -981,7 +981,7 @@
        paddr_t         sysptmap_pa;    /* System page table            */
        paddr_t         kbase;
 {
-       int             i;
+       int             nl1desc, nl2desc, i;
        st_entry_t      sg_proto, *sg, *esg;
        pt_entry_t      pg_proto, *pg, *epg;
 
@@ -1003,10 +1003,10 @@
         * pages of PTEs.  Note that we set the "used" bit
         * now to save the HW the expense of doing it.
         */
-       i   = (ptsize >> PGSHIFT) * (NPTEPG / SG4_LEV3SIZE);
+       nl2desc = (ptsize >> PGSHIFT) * (NPTEPG / SG4_LEV3SIZE);
        sg  = (st_entry_t *)sysseg_pa;
        sg  = &sg[SG4_LEV1SIZE];
-       esg = &sg[i];
+       esg = &sg[nl2desc];
        sg_proto = (ptpa + kbase) /* relocated PA */ | SG_U | SG_RW | SG_V;
        while (sg < esg) {
                *sg++     = sg_proto;
@@ -1015,13 +1015,12 @@
 
        /*
         * Initialize level 1 descriptors.  We need:
-        *      roundup(num, SG4_LEV2SIZE) / SG4_LEVEL2SIZE
-        * level 1 descriptors to map the 'num' level 2's.
+        *      roundup(nl2desc, SG4_LEV2SIZE) / SG4_LEVEL2SIZE
+        * level 1 descriptors to map the 'nl2desc' level 2's.
         */
-       i   = roundup(i, SG4_LEV2SIZE) / SG4_LEV2SIZE;
-       protostfree = (-1 << (i + 2)) /* & ~(-1 << MAXKL2SIZE) */;
+       nl1desc = roundup(nl2desc, SG4_LEV2SIZE) / SG4_LEV2SIZE;
        sg  = (st_entry_t *)sysseg_pa;
-       esg = &sg[i];
+       esg = &sg[nl1desc];
        sg_proto = ((paddr_t)&sg[SG4_LEV1SIZE] + kbase) /* relocated PA */
            | SG_U | SG_RW | SG_V;
        while (sg < esg) {
@@ -1037,10 +1036,9 @@
        /*
         * Kernel segment table at end of next level 2 table
         */
-       /* XXX fix calculations XXX */
-       i = ((((ptsize >> PGSHIFT) + 3) & -2) - 1) * (NPTEPG / SG4_LEV3SIZE);
+       i = SG4_LEV1SIZE + (nl1desc * SG4_LEV2SIZE);
        sg  = (st_entry_t *)sysseg_pa;
-       sg  = &sg[SG4_LEV1SIZE + i];
+       sg  = &sg[i + SG4_LEV2SIZE - (NPTEPG / SG4_LEV3SIZE)];
        esg = &sg[NPTEPG / SG4_LEV3SIZE];
        sg_proto = (sysptmap_pa + kbase) /* relocated PA */
            | SG_U | SG_RW | SG_V;
@@ -1048,6 +1046,7 @@
                *sg++ = sg_proto;
                sg_proto += (SG4_LEV3SIZE * sizeof(st_entry_t));
        }
+       protostfree = (-1 << (1 + nl1desc + 1)) /* & ~(-1 << MAXKL2SIZE) */;
 
        /*
         * Initialize Sysptmap

---
Izumi Tsutsui


Home | Main Index | Thread Index | Old Index