SheevaPlug boot test
Mark Tinguely
marktinguely at gmail.com
Tue Aug 3 17:23:20 UTC 2010
If someone has a SheevaPlug and a few minutes to add the following patch
to the sys/arm/mv/mv_machdep.c and boot. I am interested in the "p1 ="
and "p2 =" messages that will be at the top of the boot.
This a test that maps a physical page with cache enabled to 2 sequential
virtual addresses and does some write/cache/read operations. The virtual
addresses used for the test are just above the high vector and should
not be used for any devices. I am trying to prove to myself whether the
sheeva has a PIPT or VIPT level 2 cache.
I think I have a good idea where the Sheeva can create some cache
coherency problems related to the level 2 cache. If the Sheeva uses a
PIPT level 2 cache, it is very easy to fix. If the Sheeva uses VIPT
level 2 cache, then there will be 2 problems to fix.
Thank-you in advance,
Mark Tinguely
-------------- next part --------------
Index: mv_machdep.c
===================================================================
--- mv_machdep.c (revision 210732)
+++ mv_machdep.c (working copy)
@@ -137,6 +137,7 @@ vm_paddr_t dump_avail[4];
vm_offset_t physical_pages;
vm_offset_t pmap_bootstrap_lastaddr;
+struct pv_addr testpage;
const struct pmap_devmap *pmap_devmap_bootstrap_table;
struct pv_addr systempage;
struct pv_addr msgbufpv;
@@ -417,6 +418,7 @@ initarm(void *mdp, void *unused __unused)
* and can be shared by all processes.
*/
valloc_pages(systempage, 1);
+ valloc_pages(testpage, 1);
/* Allocate dynamic per-cpu area. */
valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE);
@@ -477,6 +479,11 @@ initarm(void *mdp, void *unused __unused)
pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa,
VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+ pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH + 0x2000, testpage.pv_pa,
+ VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+ pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH + 0x3000, testpage.pv_pa,
+ VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+
/* Map pmap_devmap[] entries */
if (platform_devmap_init() != 0)
while (1);
@@ -587,6 +594,36 @@ initarm(void *mdp, void *unused __unused)
init_param1();
init_param2(physmem);
kdb_init();
+
+#define P1ADDR (ARM_VECTORS_HIGH + 0x3000)
+#define P2ADDR (ARM_VECTORS_HIGH + 0x2000)
+ cpu_idcache_wbinv_all();
+ p1 = (int *) P1ADDR;
+ p2 = (int *) P2ADDR;
+ *p1 = 0;
+ cpu_dcache_wbinv_range(P1ADDR, 4096);
+ cpu_l2cache_wbinv_range(P1ADDR, 4096);
+ cpu_dcache_inv_range(P2ADDR, 4096);
+ cpu_l2cache_inv_range(P2ADDR, 4096);
+ printf("p2 = 0x%08x (0 RAM)\n", *p2);
+ *p1 = 0xa5a5aa55; /* remove l1, try leaving in l2 */
+ cpu_dcache_wbinv_range(P1ADDR, 4096);
+ printf("p2 = 0x%08x (0xa5a5aa55 pi or 0 vi)\n", *p2);
+ *p2 = 0x5a5a55aa; /* remove l1, try leavin in l1 of address 2 */
+ cpu_dcache_wbinv_range(P2ADDR, 4096);
+ printf("p1 = 0x%08x (0x5a5a55aa pi or 0xa5a5aa55 vi)\n", *p1);
+ cpu_dcache_inv_range(P1ADDR, 4096);
+ cpu_l2cache_inv_range(P1ADDR, 4096);
+ printf("p1 = 0x%08x (ram)\n", *p1);
+ cpu_dcache_inv_range(P1ADDR, 4096);
+ cpu_l2cache_inv_range(P1ADDR, 4096);
+ cpu_l2cache_wbinv_range(P2ADDR, 4096);
+ printf("p1 = 0x%08x (ram after a2 wb)\n", *p1);
+ *p1 = 0;
+ cpu_dcache_wbinv_range(P1ADDR, 4096);
+ cpu_l2cache_wbinv_range(P1ADDR, 4096);
+ cpu_dcache_inv_range(P2ADDR, 4096);
+ cpu_l2cache_inv_range(P2ADDR, 4096);
return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
sizeof(struct pcb)));
}
More information about the freebsd-arm
mailing list