File indexing completed on 2025-05-11 08:23:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 #undef DEBUG_MAIN
0053 #undef DEBUG
0054 #undef DEBUG_EXC
0055
0056 #ifdef DEBUG_MAIN
0057 #undef DEBUG
0058 #undef DEBUG_EXC
0059 #endif
0060
0061
0062
0063 #ifndef DEBUG_MAIN
0064 #include <rtems.h>
0065 #include <rtems/bspIo.h>
0066 #include <rtems/score/percpu.h>
0067 #include <libcpu/cpuIdent.h>
0068 #include <libcpu/spr.h>
0069 #ifdef DEBUG_EXC
0070 #include <bsp.h>
0071 #include <bsp/vectors.h>
0072 #endif
0073 #endif
0074
0075 #include <stdio.h>
0076 #include <assert.h>
0077 #include <string.h>
0078
0079 #include <libcpu/pte121.h>
0080
0081
0082
0083
0084
0085 #ifndef DEBUG_MAIN
0086
0087 #define LD_PHYS_SIZE 32
0088 #define LD_PG_SIZE 12
0089 #define LD_PTEG_SIZE 6
0090 #define LD_PTE_SIZE 3
0091 #define LD_SEG_SIZE 28
0092 #define LD_MIN_PT_SIZE 16
0093 #define LD_HASH_SIZE 19
0094 #define LD_VSID_SIZE 24
0095
0096 #else
0097
0098
0099 #define LD_PHYS_SIZE 32
0100 #define LD_PG_SIZE 6
0101 #define LD_PTEG_SIZE 5
0102 #define LD_PTE_SIZE 3
0103 #define LD_SEG_SIZE 28
0104 #define LD_MIN_PT_SIZE 7
0105 #define LD_HASH_SIZE 19
0106
0107 #endif
0108
0109
0110
0111
0112 #define LD_PI_SIZE ((LD_SEG_SIZE) - (LD_PG_SIZE))
0113
0114
0115 #define PTE_PER_PTEG (1<<((LD_PTEG_SIZE)-(LD_PTE_SIZE)))
0116
0117
0118 #define KEY_SUP (1<<30)
0119 #define KEY_USR (1<<29)
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130 #define NUM_TLB_PER_WAY 64
0131 #define FLUSH_EA_RANGE (NUM_TLB_PER_WAY<<LD_PG_SIZE)
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152 #define VSID121(ea) (((ea)>>LD_SEG_SIZE) & ((1<<(LD_PHYS_SIZE-LD_SEG_SIZE))-1))
0153
0154 #define PI121(ea) (((ea)>>LD_PG_SIZE) & ((1<<LD_PI_SIZE)-1))
0155
0156
0157 #ifndef DEBUG_MAIN
0158 static uint32_t
0159 seg2vsid (uint32_t ea)
0160 {
0161 __asm__ volatile (
0162 ".machine \"push\"\n"
0163 ".machine \"any\"\n"
0164 "mfsrin %0, %0\n"
0165 ".machine \"pop\"" :
0166 "=r" (ea) :
0167 "0" (ea)
0168 );
0169 return ea & ((1 << LD_VSID_SIZE) - 1);
0170 }
0171 #else
0172 #define seg2vsid(ea) VSID121(ea)
0173 #endif
0174
0175
0176
0177
0178 #define PTE_HASH1(vsid, pi) (((vsid)^(pi))&((1<<LD_HASH_SIZE)-1))
0179
0180
0181 #define PTE_HASH2(hash1) ((~(hash1))&((1<<LD_HASH_SIZE)-1))
0182
0183
0184
0185
0186
0187 #define API(pi) ((pi)>>((LD_MIN_PT_SIZE)-(LD_PTEG_SIZE)))
0188
0189
0190
0191 #ifdef __rtems__
0192
0193 typedef int (*PrintF) (const char *, ...);
0194 static PrintF
0195 whatPrintf (void)
0196 {
0197 return _Thread_Executing ? printf : printk;
0198 }
0199
0200 #define PRINTF(args...) ((void)(whatPrintf())(args))
0201 #else
0202 #define PRINTF(args...) printf(args)
0203 #endif
0204
0205 #ifdef DEBUG
0206 static unsigned long triv121PgTblConsistency(
0207 Triv121PgTbl pt, int pass, int expect);
0208
0209 static int consistencyPass = 0;
0210 #define CONSCHECK(expect) triv121PgTblConsistency(&pgTbl,consistencyPass++,(expect))
0211 #else
0212 #define CONSCHECK(expect) do {} while (0)
0213 #endif
0214
0215
0216
0217
0218 typedef struct Triv121PgTblRec_
0219 {
0220 APte base;
0221 unsigned long size;
0222 int active;
0223 } Triv121PgTblRec;
0224
0225
0226
0227
0228 #ifdef DEBUG_EXC
0229 static void myhdl (BSP_Exception_frame * excPtr);
0230 #endif
0231
0232 static void dumpPte (APte pte);
0233
0234 #ifdef DEBUG
0235 static void
0236 dumpPteg (unsigned long vsid, unsigned long pi, unsigned long hash);
0237 #endif
0238
0239 unsigned long
0240 triv121IsRangeMapped (long vsid, unsigned long start, unsigned long end);
0241
0242 static void do_dssall (void);
0243
0244
0245
0246
0247
0248
0249 static Triv121PgTblRec pgTbl = { 0 };
0250
0251 #ifdef DEBUG_EXC
0252 static void *ohdl;
0253 #endif
0254
0255
0256
0257
0258 static inline APte
0259 ptegOf (Triv121PgTbl pt, unsigned long hash)
0260 {
0261 hash &= ((1 << LD_HASH_SIZE) - 1);
0262 return (APte) (((unsigned long) pt->
0263 base) | ((hash << LD_PTEG_SIZE) & (pt->size - 1)));
0264 }
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274 static APte
0275 alreadyMapped (Triv121PgTbl pt, long vsid, unsigned long pi)
0276 {
0277 int i;
0278 unsigned long hash, api;
0279 APte pte;
0280
0281 if (!pt->size)
0282 return 0;
0283
0284 if (TRIV121_121_VSID == vsid) {
0285 vsid = VSID121 (pi);
0286 pi = PI121 (pi);
0287 } else if (TRIV121_SEG_VSID == vsid) {
0288 vsid = seg2vsid (pi);
0289 pi = PI121 (pi);
0290 }
0291
0292 hash = PTE_HASH1 (vsid, pi);
0293 api = API (pi);
0294 for (i = 0, pte = ptegOf (pt, hash); i < PTE_PER_PTEG; i++, pte++)
0295 if (pte->v && pte->vsid == vsid && pte->api == api && 0 == pte->h)
0296 return pte;
0297
0298 hash = PTE_HASH2 (hash);
0299 for (i = 0, pte = ptegOf (pt, hash); i < PTE_PER_PTEG; i++, pte++)
0300 if (pte->v && pte->vsid == vsid && pte->api == api && 1 == pte->h)
0301 return pte;
0302 return 0;
0303 }
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314 static APte
0315 slotFor (Triv121PgTbl pt, unsigned long vsid, unsigned long pi)
0316 {
0317 int i;
0318 unsigned long hash;
0319 APte pte;
0320
0321
0322 hash = PTE_HASH1 (vsid, pi);
0323
0324 for (i = 0, pte = ptegOf (pt, hash); i < PTE_PER_PTEG; i++, pte++) {
0325 if (!pte->v && !pte->marked) {
0326
0327 pte->h = 0;
0328 pte->marked = 1;
0329 return pte;
0330 }
0331 }
0332
0333 #ifdef DEBUG
0334
0335
0336
0337
0338 PRINTF ("## First hash bucket full - ");
0339 dumpPteg (vsid, pi, hash);
0340 #endif
0341
0342 hash = PTE_HASH2 (hash);
0343 #ifdef DEBUG
0344 PRINTF (" Secondary pteg is 0x%08x\n", (unsigned) ptegOf (pt, hash));
0345 #endif
0346 for (i = 0, pte = ptegOf (pt, hash); i < PTE_PER_PTEG; i++, pte++) {
0347 if (!pte->v && !pte->marked) {
0348
0349 pte->marked = 1;
0350 pte->h = 1;
0351 return pte;
0352 }
0353 }
0354 #ifdef DEBUG
0355
0356 PRINTF ("## Second hash bucket full - ");
0357 dumpPteg (vsid, pi, hash);
0358 #endif
0359 return 0;
0360 }
0361
0362
0363 static void
0364 unmarkAll (Triv121PgTbl pt)
0365 {
0366 unsigned long n = pt->size / sizeof (PTERec);
0367 unsigned long i;
0368 APte pte;
0369 for (i = 0, pte = pt->base; i < n; i++, pte++)
0370 pte->marked = 0;
0371
0372 }
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383 unsigned long
0384 triv121PgTblLdMinSize (unsigned long size)
0385 {
0386 unsigned long i;
0387
0388 size += (1 << LD_PG_SIZE) - 1;
0389 size &= ~((1 << LD_PG_SIZE) - 1);
0390
0391
0392
0393 size >>= LD_PG_SIZE - LD_PTE_SIZE;
0394
0395 for (i = 0; i < LD_PHYS_SIZE; i++) {
0396 if ((1 << i) >= size)
0397 break;
0398 }
0399
0400 if (i < LD_MIN_PT_SIZE)
0401 i = LD_MIN_PT_SIZE;
0402 return i;
0403 }
0404
0405
0406
0407
0408
0409
0410
0411 Triv121PgTbl
0412 triv121PgTblInit (unsigned long base, unsigned ldSize)
0413 {
0414 if (pgTbl.size) {
0415
0416 return 0;
0417 }
0418
0419 if (ldSize < LD_MIN_PT_SIZE)
0420 return 0;
0421
0422 if (base & ((1 << ldSize) - 1))
0423 return 0;
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438 if ( ! ppc_cpu_has_hw_ptbl_lkup() )
0439 return 0;
0440
0441 pgTbl.base = (APte) base;
0442 pgTbl.size = 1 << ldSize;
0443
0444 memset (pgTbl.base, 0, pgTbl.size);
0445
0446 CONSCHECK (0);
0447
0448
0449 if (triv121PgTblMap (&pgTbl,
0450 TRIV121_121_VSID,
0451 base,
0452 (pgTbl.size >> LD_PG_SIZE),
0453 TRIV121_ATTR_M, TRIV121_PP_RO_PAGE) >= 0)
0454 return 0;
0455
0456 CONSCHECK ((pgTbl.size >> LD_PG_SIZE));
0457
0458 return &pgTbl;
0459 }
0460
0461
0462
0463
0464 Triv121PgTbl
0465 triv121PgTblGet (void)
0466 {
0467 return pgTbl.size ? &pgTbl : 0;
0468 }
0469
0470
0471
0472
0473
0474
0475
0476
0477 long
0478 triv121PgTblMap (Triv121PgTbl pt,
0479 long ovsid,
0480 unsigned long start,
0481 unsigned long numPages,
0482 unsigned attributes, unsigned protection)
0483 {
0484 int i, pass;
0485 unsigned long pi;
0486 APte pte;
0487 long vsid;
0488 #ifdef DEBUG
0489 long saved_vsid = ovsid;
0490 #endif
0491
0492 if (TRIV121_121_VSID == ovsid) {
0493
0494 ovsid = VSID121 (start);
0495 } else if (TRIV121_SEG_VSID == ovsid) {
0496 ovsid = seg2vsid (start);
0497 }
0498
0499 #ifdef DEBUG
0500 PRINTF ("Mapping %i (0x%x) pages at 0x%08x for VSID 0x%08x\n",
0501 (unsigned) numPages, (unsigned) numPages,
0502 (unsigned) start, (unsigned) ovsid);
0503 #endif
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517 for (pass = 0; pass < 2; pass++) {
0518
0519 for (i = 0, pi = PI121 (start), vsid = ovsid; i < numPages; i++, pi++) {
0520 if (pi >= 1 << LD_PI_SIZE) {
0521 vsid++;
0522 pi = 0;
0523 }
0524
0525 if (!alreadyMapped (pt, vsid, pi)) {
0526 if (!(pte = slotFor (pt, vsid, pi))) {
0527
0528 unmarkAll (pt);
0529 return pi;
0530 } else {
0531
0532 if (pass) {
0533
0534 pte->vsid = vsid;
0535
0536 pte->api = API (pi);
0537
0538 pte->rpn =
0539 ((((unsigned long) vsid) &
0540 ((1 << (LD_PHYS_SIZE - LD_SEG_SIZE)) -
0541 1)) << LD_PI_SIZE) | pi;
0542 pte->wimg = attributes & 0xf;
0543 pte->pp = protection & 0x3;
0544
0545 pte->marked = 0;
0546 if (pt->active) {
0547 uint32_t flags;
0548 rtems_interrupt_disable (flags);
0549
0550 __asm__ volatile ("eieio":::"memory");
0551 pte->v = 1;
0552 __asm__ volatile ("sync":::"memory");
0553 rtems_interrupt_enable (flags);
0554 } else {
0555 pte->v = 1;
0556 }
0557
0558 #ifdef DEBUG
0559
0560 assert (alreadyMapped (pt, vsid, pi) == pte);
0561 #endif
0562 }
0563 }
0564 }
0565 }
0566 unmarkAll (pt);
0567 }
0568 #ifdef DEBUG
0569 {
0570 unsigned long failedat;
0571 CONSCHECK (-1);
0572
0573 failedat =
0574 triv121IsRangeMapped (saved_vsid, start,
0575 start + (1 << LD_PG_SIZE) * numPages);
0576 if (0x0C0C != failedat) {
0577 PRINTF ("triv121 mapping failed at 0x%08x\n", (unsigned) failedat);
0578 return PI121 (failedat);
0579 }
0580 }
0581 #endif
0582 return TRIV121_MAP_SUCCESS;
0583 }
0584
0585 unsigned long
0586 triv121PgTblSDR1 (Triv121PgTbl pt)
0587 {
0588 return (((unsigned long) pt->base) & ~((1 << LD_MIN_PT_SIZE) - 1)) |
0589 (((pt->size - 1) >> LD_MIN_PT_SIZE) &
0590 ((1 << (LD_HASH_SIZE - (LD_MIN_PT_SIZE - LD_PTEG_SIZE))) - 1)
0591 );
0592 }
0593
0594 void
0595 triv121PgTblActivate (Triv121PgTbl pt)
0596 {
0597 #ifndef DEBUG_MAIN
0598 unsigned long sdr1 = triv121PgTblSDR1 (pt);
0599 register unsigned long tmp0 = 16;
0600 register unsigned long tmp1 = (KEY_USR | KEY_SUP);
0601 register unsigned long tmp2 = (MSR_EE | MSR_IR | MSR_DR);
0602 #endif
0603 pt->active = 1;
0604
0605 #ifndef DEBUG_MAIN
0606 #ifdef DEBUG_EXC
0607
0608 ohdl = globalExceptHdl;
0609 globalExceptHdl = myhdl;
0610 __asm__ __volatile__ ("sync"::"memory");
0611 #endif
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629 __asm__ __volatile (
0630 " .machine \"push\"\n"
0631 " .machine \"any\"\n"
0632 " mtctr %[tmp0]\n"
0633
0634
0635
0636
0637
0638
0639
0640 " mfmsr %[tmp0]\n"
0641 " andc %[tmp2], %[tmp0], %[tmp2]\n"
0642 " mtmsr %[tmp2]\n"
0643 " isync \n"
0644
0645 " li %[tmp2], 0\n"
0646 "1: mtsrin %[tmp1], %[tmp2]\n"
0647 " addis %[tmp2], %[tmp2], 0x1000\n"
0648 " addi %[tmp1], %[tmp1], 1\n"
0649 " bdnz 1b\n"
0650
0651 " lis %[tmp2], %[ea_range]@h\n"
0652 "2: addic. %[tmp2], %[tmp2], -%[pg_sz]\n"
0653 " tlbie %[tmp2], 0\n"
0654 " bgt 2b\n"
0655 " eieio \n"
0656 " tlbsync \n"
0657 " sync \n"
0658
0659 " mtspr %[sdr1], %[sdr1val]\n"
0660
0661 " mtmsr %[tmp0]\n"
0662 " isync \n"
0663 " .machine \"pop\"\n"
0664 :[tmp0]"+r&"(tmp0), [tmp1]"+b&"(tmp1), [tmp2]"+b&"(tmp2)
0665 :[ea_range]"i"(FLUSH_EA_RANGE), [pg_sz]"i" (1 << LD_PG_SIZE),
0666 [sdr1]"i"(SDR1), [sdr1val]"r" (sdr1)
0667 :"ctr", "cc", "memory"
0668 );
0669
0670
0671
0672
0673 #endif
0674 }
0675
0676
0677
0678
0679 #ifdef DEBUG_EXC
0680
0681 #define BAT_VALID_BOTH 3
0682
0683 static void
0684 myhdl (BSP_Exception_frame * excPtr)
0685 {
0686 if (3 == excPtr->_EXC_number) {
0687 unsigned long dsisr;
0688
0689
0690 __asm__ __volatile__ (
0691 "mfspr %0, %1 \n"
0692 "ori %0, %0, 3\n"
0693 "mtspr %1, %0 \n"
0694 "sync\n"
0695 "mfspr %0, %2\n"
0696 :"=&r" (dsisr)
0697 :"i" (DBAT0U), "i" (DSISR), "i" (BAT_VALID_BOTH)
0698 );
0699
0700 printk ("Data Access Exception (DSI) # 3\n");
0701 printk ("Reactivated DBAT0 mapping\n");
0702
0703
0704 printk ("DSISR 0x%08x\n", dsisr);
0705
0706 printk ("revectoring to prevent default handler panic().\n");
0707 printk ("NOTE: exception number %i below is BOGUS\n", ASM_DEC_VECTOR);
0708
0709
0710
0711
0712
0713
0714 excPtr->_EXC_number = ASM_DEC_VECTOR;
0715 }
0716
0717 ((void (*)()) ohdl) (excPtr);
0718 }
0719 #endif
0720
0721
0722
0723 #ifdef DEBUG
0724
0725
0726
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741
0742 static unsigned long
0743 triv121PgTblConsistency (Triv121PgTbl pt, int pass, int expected)
0744 {
0745 APte pte;
0746 int i;
0747 unsigned v, m;
0748 int warn = 0;
0749 int errs = 0;
0750 static int maxw = 20;
0751
0752 PRINTF ("Checking page table at 0x%08x (size %i==0x%x)\n",
0753 (unsigned) pt->base, (unsigned) pt->size, (unsigned) pt->size);
0754
0755 if (!pt->base || !pt->size) {
0756 PRINTF ("Uninitialized Page Table!\n");
0757 return 0;
0758 }
0759
0760 v = m = 0;
0761 #if 1
0762
0763
0764
0765
0766
0767
0768
0769
0770
0771
0772
0773 for (i = pt->size / sizeof (PTERec) - 1, pte = pt->base + i; i >= 0;
0774 i--, pte--)
0775 #else
0776 for (i = 0, pte = pt->base; i < pt->size / sizeof (PTERec); i++, pte++)
0777 #endif
0778 {
0779 int err = 0;
0780 char buf[500];
0781 unsigned long *lp = (unsigned long *) pte;
0782 #if 0
0783
0784
0785
0786 while (pte >= pt->base + pt->size / sizeof (PTERec))
0787 ;
0788 #endif
0789
0790 if ( (*(lp + 1) & 0xe00)
0791 || (pte->v && pte->marked)) {
0792
0793 sprintf (buf, "unused bits or v && m");
0794 err = 1;
0795 } else {
0796 if ( (*lp & (0xfffff0 << 7)) ) {
0797 sprintf(buf,"(warning) non-1:1 VSID found");
0798 err = 2;
0799 }
0800 if (pte->v)
0801 v++;
0802 if (pte->marked)
0803 m++;
0804 }
0805 if (err && maxw) {
0806 PRINTF
0807 ("Pass %i -- strange PTE at 0x%08x found for page index %i == 0x%08x:\n",
0808 pass, (unsigned) pte, i, i);
0809 PRINTF ("Reason: %s\n", buf);
0810 dumpPte (pte);
0811 if ( err & 2 ) {
0812 warn++;
0813 } else {
0814 errs++;
0815 }
0816 maxw--;
0817 }
0818 }
0819 if (errs) {
0820 PRINTF ("%i errors %s", errs, warn ? "and ":"");
0821 }
0822 if (warn) {
0823 PRINTF ("%i warnings ",warn);
0824 }
0825 if (errs || warn) {
0826 PRINTF ("found; currently %i entries marked, %i are valid\n",
0827 m, v);
0828 }
0829 v += m;
0830 if (maxw && expected >= 0 && expected != v) {
0831
0832 PRINTF ("Wrong # of occupied slots detected during pass");
0833 PRINTF ("%i; should be %i (0x%x) is %i (0x%x)\n",
0834 pass, expected, (unsigned) expected, v, (unsigned) v);
0835 maxw--;
0836 }
0837 return v;
0838 }
0839 #endif
0840
0841
0842
0843
0844 APte
0845 triv121DumpEa (unsigned long ea)
0846 {
0847 APte pte;
0848
0849 pte =
0850 alreadyMapped (&pgTbl, pgTbl.active ? TRIV121_SEG_VSID : TRIV121_121_VSID,
0851 ea);
0852
0853 if (pte)
0854 dumpPte (pte);
0855 return pte;
0856 }
0857
0858 APte
0859 triv121FindPte (unsigned long vsid, unsigned long pi)
0860 {
0861 return alreadyMapped (&pgTbl, vsid, pi);
0862 }
0863
0864 APte
0865 triv121UnmapEa (unsigned long ea)
0866 {
0867 uint32_t flags;
0868 APte pte;
0869
0870 if (!pgTbl.active) {
0871 pte = alreadyMapped (&pgTbl, TRIV121_121_VSID, ea);
0872 if (pte)
0873 pte->v = 0;
0874 return pte;
0875 }
0876
0877 pte = alreadyMapped (&pgTbl, TRIV121_SEG_VSID, ea);
0878
0879 if (!pte)
0880 return 0;
0881
0882 rtems_interrupt_disable (flags);
0883 pte->v = 0;
0884 do_dssall ();
0885 __asm__ volatile (" sync \n\t"
0886 " tlbie %0, 0 \n\t"
0887 " eieio \n\t"
0888 " tlbsync \n\t"
0889 " sync \n\t"::"r" (ea):"memory");
0890 rtems_interrupt_enable (flags);
0891 return pte;
0892 }
0893
0894
0895 #define SYNC_LONGJMP(msr) \
0896 asm volatile( \
0897 " mtsrr1 %0 \n\t" \
0898 " bl 1f \n\t" \
0899 "1: mflr 3 \n\t" \
0900 " addi 3,3,1f-1b \n\t" \
0901 " mtsrr0 3 \n\t" \
0902 " rfi \n\t" \
0903 "1: \n\t" \
0904 : \
0905 :"r"(msr) \
0906 :"3","lr","memory")
0907
0908
0909
0910
0911
0912
0913 static void
0914 do_dssall (void)
0915 {
0916
0917
0918
0919
0920
0921
0922
0923
0924 if ( (_read_MSR () & MSR_VE) && PPC_PSIM != get_ppc_cpu_type() ) {
0925
0926
0927
0928
0929
0930
0931 #define DSSALL 0x7e00066c
0932 __asm__ volatile (" .long %0"::"i" (DSSALL));
0933 #undef DSSALL
0934 }
0935 }
0936
0937 APte
0938 triv121ChangeEaAttributes (unsigned long ea, int wimg, int pp)
0939 {
0940 APte pte;
0941 unsigned long msr;
0942
0943 if (!pgTbl.active) {
0944 pte = alreadyMapped (&pgTbl, TRIV121_121_VSID, ea);
0945 if (!pte)
0946 return 0;
0947 if (wimg > 0)
0948 pte->wimg = wimg;
0949 if (pp > 0)
0950 pte->pp = pp;
0951 return pte;
0952 }
0953
0954 pte = alreadyMapped (&pgTbl, TRIV121_SEG_VSID, ea);
0955
0956 if (!pte)
0957 return 0;
0958
0959 if (wimg < 0 && pp < 0)
0960 return pte;
0961
0962 __asm__ volatile ("mfmsr %0":"=r" (msr));
0963
0964
0965 SYNC_LONGJMP (msr & ~(MSR_EE | MSR_DR | MSR_IR));
0966
0967 pte->v = 0;
0968 do_dssall ();
0969 __asm__ volatile ("sync":::"memory");
0970 if (wimg >= 0)
0971 pte->wimg = wimg;
0972 if (pp >= 0)
0973 pte->pp = pp;
0974 __asm__ volatile ("tlbie %0, 0; eieio"::"r" (ea):"memory");
0975 pte->v = 1;
0976 __asm__ volatile ("tlbsync; sync":::"memory");
0977
0978
0979 SYNC_LONGJMP (msr);
0980
0981 return pte;
0982 }
0983
0984 static void
0985 pgtblChangePP (Triv121PgTbl pt, int pp)
0986 {
0987 unsigned long n = pt->size >> LD_PG_SIZE;
0988 unsigned long b, i;
0989
0990 for (i = 0, b = (unsigned long) pt->base; i < n;
0991 i++, b += (1 << LD_PG_SIZE)) {
0992 triv121ChangeEaAttributes (b, -1, pp);
0993 }
0994 }
0995
0996 void
0997 triv121MakePgTblRW ()
0998 {
0999 pgtblChangePP (&pgTbl, TRIV121_PP_RW_PAGE);
1000 }
1001
1002 void
1003 triv121MakePgTblRO ()
1004 {
1005 pgtblChangePP (&pgTbl, TRIV121_PP_RO_PAGE);
1006 }
1007
1008 long
1009 triv121DumpPte (APte pte)
1010 {
1011 if (pte)
1012 dumpPte (pte);
1013 return 0;
1014 }
1015
1016
1017 #ifdef DEBUG
1018
1019
1020 static void
1021 dumpPteg (unsigned long vsid, unsigned long pi, unsigned long hash)
1022 {
1023 APte pte = ptegOf (&pgTbl, hash);
1024 int i;
1025 PRINTF ("hash 0x%08x, pteg 0x%08x (vsid 0x%08x, pi 0x%08x)\n",
1026 (unsigned) hash, (unsigned) pte, (unsigned) vsid, (unsigned) pi);
1027 for (i = 0; i < PTE_PER_PTEG; i++, pte++) {
1028 PRINTF ("pte 0x%08x is 0x%08x : 0x%08x\n",
1029 (unsigned) pte,
1030 (unsigned) *(unsigned long *) pte,
1031 (unsigned) *(((unsigned long *) pte) + 1));
1032 }
1033 }
1034 #endif
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048 unsigned long
1049 triv121IsRangeMapped (long vsid, unsigned long start, unsigned long end)
1050 {
1051 unsigned pi;
1052
1053 start &= ~((1 << LD_PG_SIZE) - 1);
1054 while (start < end) {
1055 if ( TRIV121_SEG_VSID != vsid && TRIV121_121_VSID != vsid )
1056 pi = PI121(start);
1057 else
1058 pi = start;
1059 if (!alreadyMapped (&pgTbl, vsid, pi))
1060 return start;
1061 start += 1 << LD_PG_SIZE;
1062 }
1063 return 0x0C0C;
1064 }
1065
1066
1067 #include <stdlib.h>
1068
1069
1070 static void
1071 dumpPte (APte pte)
1072 {
1073 if (0 == ((unsigned long) pte & ((1 << LD_PTEG_SIZE) - 1)))
1074 PRINTF ("PTEG--");
1075 else
1076 PRINTF ("......");
1077 if (pte->v) {
1078 PRINTF ("VSID: 0x%08x H:%1i API: 0x%02x\n", pte->vsid, pte->h, pte->api);
1079 PRINTF (" ");
1080 PRINTF ("RPN: 0x%08x WIMG: 0x%1x, (m %1i), pp: 0x%1x\n",
1081 pte->rpn, pte->wimg, pte->marked, pte->pp);
1082 } else {
1083 PRINTF ("xxxxxx\n");
1084 PRINTF (" ");
1085 PRINTF ("xxxxxx\n");
1086 }
1087 }
1088
1089
1090 #if defined(DEBUG_MAIN)
1091
1092
1093
1094
1095
1096
1097 int
1098 triv121PgTblDump (Triv121PgTbl pt, unsigned from, unsigned to)
1099 {
1100 int i;
1101 APte pte;
1102 PRINTF ("Dumping PT [size 0x%08x == %i] at 0x%08x\n",
1103 (unsigned) pt->size, (unsigned) pt->size, (unsigned) pt->base);
1104 if (from > pt->size >> LD_PTE_SIZE)
1105 from = 0;
1106 if (to > pt->size >> LD_PTE_SIZE)
1107 to = (pt->size >> LD_PTE_SIZE);
1108 for (i = from, pte = pt->base + from; i < (long) to; i++, pte++) {
1109 dumpPte (pte);
1110 }
1111 return 0;
1112 }
1113
1114
1115
1116 #define LD_DBG_PT_SIZE LD_MIN_PT_SIZE
1117
1118 int
1119 main (int argc, char **argv)
1120 {
1121 unsigned long base, start, numPages;
1122 unsigned long size = 1 << LD_DBG_PT_SIZE;
1123 Triv121PgTbl pt;
1124
1125 base = (unsigned long) malloc (size << 1);
1126
1127 assert (base);
1128
1129
1130 base += size - 1;
1131 base &= ~(size - 1);
1132
1133 assert (pt = triv121PgTblInit (base, LD_DBG_PT_SIZE));
1134
1135 triv121PgTblDump (pt, (unsigned) -1, (unsigned) -1);
1136 do {
1137 do {
1138 PRINTF ("Start Address:");
1139 fflush (stdout);
1140 } while (1 != scanf ("%i", &start));
1141 do {
1142 PRINTF ("# pages:");
1143 fflush (stdout);
1144 } while (1 != scanf ("%i", &numPages));
1145 } while (TRIV121_MAP_SUCCESS ==
1146 triv121PgTblMap (pt, TRIV121_121_VSID, start, numPages,
1147 TRIV121_ATTR_IO_PAGE, 2)
1148 && 0 == triv121PgTblDump (pt, (unsigned) -1, (unsigned) -1));
1149 }
1150 #endif