From bee0c94fb4a5a8c798c9a7ae5810b966c4e0beae Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Thu, 7 May 2020 12:08:43 +1000 Subject: [PATCH] tests/privileged: Update for instruction translation Since setting MSR[PR] = 1 forces instruction translation on, we need to set up translations for the problem state code to use. Signed-off-by: Paul Mackerras --- tests/privileged/privileged.c | 91 ++++++++++++++++++++++++++++++++++ tests/test_privileged.bin | Bin 9900 -> 16400 bytes 2 files changed, 91 insertions(+) diff --git a/tests/privileged/privileged.c b/tests/privileged/privileged.c index 073dc07..eca6e0e 100644 --- a/tests/privileged/privileged.c +++ b/tests/privileged/privileged.c @@ -55,6 +55,94 @@ void print_test_number(int i) putchar(':'); } +static inline void do_tlbie(unsigned long rb, unsigned long rs) +{ + __asm__ volatile("tlbie %0,%1" : : "r" (rb), "r" (rs) : "memory"); +} + +static inline void store_pte(unsigned long *p, unsigned long pte) +{ + __asm__ volatile("stdbrx %1,0,%0" : : "r" (p), "r" (pte) : "memory"); +} + +#define CACHE_LINE_SIZE 64 + +void zero_memory(void *ptr, unsigned long nbytes) +{ + unsigned long nb, i, nl; + void *p; + + for (; nbytes != 0; nbytes -= nb, ptr += nb) { + nb = -((unsigned long)ptr) & (CACHE_LINE_SIZE - 1); + if (nb == 0 && nbytes >= CACHE_LINE_SIZE) { + nl = nbytes / CACHE_LINE_SIZE; + p = ptr; + for (i = 0; i < nl; ++i) { + __asm__ volatile("dcbz 0,%0" : : "r" (p) : "memory"); + p += CACHE_LINE_SIZE; + } + nb = nl * CACHE_LINE_SIZE; + } else { + if (nb > nbytes) + nb = nbytes; + for (i = 0; i < nb; ++i) + ((unsigned char *)ptr)[i] = 0; + } + } +} + +#define PERM_EX 0x001 +#define PERM_WR 0x002 +#define PERM_RD 0x004 +#define PERM_PRIV 0x008 +#define ATTR_NC 0x020 +#define CHG 0x080 +#define REF 0x100 + +#define DFLT_PERM (PERM_WR | PERM_RD | REF | CHG) + +/* + * Set up an MMU translation tree using memory starting at the 64k point. + * We use 2 levels, mapping 2GB (the minimum size possible), with a + * 8kB PGD level pointing to 4kB PTE pages. + */ +unsigned long *pgdir = (unsigned long *) 0x10000; +unsigned long free_ptr = 0x12000; + +void init_mmu(void) +{ + zero_memory(pgdir, 1024 * sizeof(unsigned long)); + /* RTS = 0 (2GB address space), RPDS = 10 (1024-entry top level) */ + mtspr(720, (unsigned long) pgdir | 10); + do_tlbie(0xc00, 0); /* invalidate all TLB entries */ +} + +static unsigned long *read_pgd(unsigned long i) +{ + unsigned long ret; + + __asm__ volatile("ldbrx %0,%1,%2" : "=r" (ret) : "b" (pgdir), + "r" (i * sizeof(unsigned long))); + return (unsigned long *) (ret & 0x00ffffffffffff00); +} + +void map(unsigned long ea, unsigned long pa, unsigned long perm_attr) +{ + unsigned long epn = ea >> 12; + unsigned long i, j; + unsigned long *ptep; + + i = (epn >> 9) & 0x3ff; + j = epn & 0x1ff; + if (pgdir[i] == 0) { + zero_memory((void *)free_ptr, 512 * sizeof(unsigned long)); + store_pte(&pgdir[i], 0x8000000000000000 | free_ptr | 9); + free_ptr += 512 * sizeof(unsigned long); + } + ptep = read_pgd(i); + store_pte(&ptep[j], 0xc000000000000000 | (pa & 0x00fffffffffff000) | perm_attr); +} + int priv_fn_1(unsigned long x) { __asm__ volatile("attn"); @@ -140,6 +228,9 @@ void do_test(int num, int (*fn)(unsigned long)) int main(void) { potato_uart_init(); + init_mmu(); + map(0x2000, 0x2000, REF | CHG | PERM_RD | PERM_EX); /* map code page */ + map(0x7000, 0x7000, REF | CHG | PERM_RD | PERM_WR); /* map stack page */ do_test(1, priv_fn_1); do_test(2, priv_fn_2); diff --git a/tests/test_privileged.bin b/tests/test_privileged.bin index 5b8ce63ab5e843bf8ff40c84d36833ad52abd0ca..6eb6b536b11ab8f75b5663faf5dcc4fea6c94e0e 100755 GIT binary patch delta 1554 zcmZ8hT}&KR6h1Ss>r!!94bg2OF#AK@L1Hle%~CA0Kr7uX%^I=x!H1<_+8C{1d>CY= zI}mD0(g$$jlOS!Pq%ln+K@&|hX)BtT_|V4GV656!ngHtqF=!SRynbf@L%7M!-0wTz zIrpBQ-AnBwwlorxD{H1|f2wYr6`h6KVxTZDE)sFO#WLGM*RI%$l?^Y?ddx%+G{K>FKCxM21Zt{EZh6SrRR1L^}Ky%vqr~Uw)wo zTr$2agp_i=QiA*Wp`5jmYO+YNHJ^Qao-1%eg!1i(=(EEMyGZSvoUXU1RKbh&cz05_ z>M5kvtvioL+(a@g`+iNN@^7E+n1ZVjnJ|sVzBccEY#Oyoszs#MwIVsbjsmtuxaQ}7 zMT#-|lHH6=&wY2FudjrBo#lV2meG>5V(q#`Y!9e$d{?&gv1QeoYo6<$Yf+!y*{pOI^BISt`Ga_O3LG@Q(~ zuZxsX_#^u&lJ2X>nrMqI#PP1t>x&^N|&S^WJS;& zFFn3^G=f1?d-GyY_d&FHq|4bC4Y^JMj&iWp^1<%B9<4uC9{wh4pe0*#sV_B|rDzYg zCAPwS&7PG=?0X;i&SB$uyd+yD;$IM6t6dJ(VhBszUz>y<X3e`;#8hgXDP zIUOiT(1-GbbkJY_VB&PzPl?}u^CsNql}beCp*zPqEQL3?;HnVEm|))t>459m#-83p zJ?K_w4nuQgOOyD(Ggdra#Mj`CW`DZ-5%->7Z~cO+HUb-Pnq760d#k)-I6hTyPVEiv zp22aZAjFIt%CEq^+fS|Dg!6Pwb+%(o2p$k#TlF-+ab0;ar(=)o;JBU_!8PK`i*;^2 zx5bNr;{q*%OXK^0p<3N^TXy;BVYgKG!^QzFVh7iSh)s`{y&0H3U)Jj><7&BUTV-CI(6TtVX4W9tvJ!OQ7D=Q&W@f5_%F3 zse?zwQxPemcNM{l2QT6WcoAzr+S+0T4_lKs{wMCCWZ=R3{ojAy&YRhmrL0_PC0QZz zEdA*qFK9Nq>f%}bCfj2Cv7TpYm4DYm`6Wi@TH)ojr$s_3v0 zx>lE0&MWbtU$ss;rgWqIGg0Gj;+ZKS77Za@9}k4vCVJcNgl-q@m&hNK6k51*ALrdh z$on-qyB|otla_ljeyTxq`-r#iPvxX{t{iFH^#*t)anXGBM+i+?v2a2e3Q_=4rsH`HV5|Bq5a;aMZqmZ7aIONekiH4V258$rrB(V&nH8}8meA}=y`|x kQXx+U>1dZ9O@)I~NFQ~DcnAlb@o6Kag)2Tf?I{8O0m91$6951J