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