| 1 | #include <linux/config.h>\r |
| 2 | #include <linux/module.h>\r |
| 3 | #include <linux/kernel.h>\r |
| 4 | #include <linux/init.h>\r |
| 5 | #include <linux/miscdevice.h>\r |
| 6 | #include <asm/memory.h>\r |
| 7 | \r |
| 8 | #define MMUHACK_MINOR 225\r |
| 9 | #define DEVICE_NAME "mmuhack"\r |
| 10 | \r |
| 11 | #if __GNUC__ == 3\r |
| 12 | #include <linux/version.h>\r |
| 13 | static const char __module_kernel_version_gcc3[] __attribute__((__used__)) __attribute__((section(".modinfo"))) =\r |
| 14 | "kernel_version=" UTS_RELEASE;\r |
| 15 | #endif\r |
| 16 | \r |
| 17 | static ssize_t mmuhack_open(struct inode *inode, struct file *filp)\r |
| 18 | {\r |
| 19 | unsigned int *pgtable;\r |
| 20 | unsigned int *cpt;\r |
| 21 | int i, j;\r |
| 22 | int ttb;\r |
| 23 | int ret = -EFAULT;\r |
| 24 | \r |
| 25 | // get the pointer to the translation table base...\r |
| 26 | asm volatile(\r |
| 27 | "stmdb sp!, {r0}\n\t"\r |
| 28 | "mrc p15, 0, r0, c2, c0, 0\n\t"\r |
| 29 | "mov %0, r0\n\t"\r |
| 30 | "ldmia sp!, {r0}\n\t": "=r"(ttb)\r |
| 31 | );\r |
| 32 | \r |
| 33 | pgtable = __va(ttb);\r |
| 34 | \r |
| 35 | for (i = 0; i < 4096; i ++) if ( (pgtable[i] & 3) == 1 ) {\r |
| 36 | cpt = __va(pgtable[i] & 0xfffffc00);\r |
| 37 | \r |
| 38 | for (j = 0; j < 256; j ++) {/*\r |
| 39 | if ( (cpt[j] & 0xfe00000f) == 0x02000002 ) {\r |
| 40 | // set C and B bits in upper 32MB memory area...\r |
| 41 | printk("Set C&B bits %08x\n",cpt[j]);\r |
| 42 | cpt[j] |= 0xFFC;\r |
| 43 | ret = 0;\r |
| 44 | }\r |
| 45 | */\r |
| 46 | if (((cpt[j] & 0xff000000) == 0x02000000) && ((cpt[j] & 12)==0) )\r |
| 47 | {\r |
| 48 | //printk("Set C&B bits %08x\n",cpt[j]);\r |
| 49 | cpt[j] |= 0xFFC;\r |
| 50 | }\r |
| 51 | //if ((a>=0x31 && a<=0x36) && ((cpt[i] & 12)==0))\r |
| 52 | if (((cpt[j] & 0xff000000) == 0x03000000) && ((cpt[j] & 12)==0))\r |
| 53 | {\r |
| 54 | //printk("Set C&B bits %08x\n",cpt[j]);\r |
| 55 | //printf("SDL c and b bits not set, overwriting\n");\r |
| 56 | cpt[j] |= 0xFFC;\r |
| 57 | }\r |
| 58 | }\r |
| 59 | }\r |
| 60 | \r |
| 61 | // drain the write buffer and flush the tlb caches...\r |
| 62 | asm volatile(\r |
| 63 | "stmdb sp!, {r0}\n\t"\r |
| 64 | "mov r0, #0\n\t"\r |
| 65 | "mcr 15, 0, r0, cr7, cr10, 4\n\t"\r |
| 66 | "mcr 15, 0, r0, cr8, cr7, 0\n\t"\r |
| 67 | "ldmia sp!, {r0}\n\t"\r |
| 68 | );\r |
| 69 | \r |
| 70 | if (ret == 0)\r |
| 71 | printk("MMU hack applied.\n");\r |
| 72 | \r |
| 73 | return 0;\r |
| 74 | }\r |
| 75 | \r |
| 76 | static struct file_operations mmuhack_fops = {\r |
| 77 | owner: THIS_MODULE,\r |
| 78 | open: mmuhack_open,\r |
| 79 | };\r |
| 80 | \r |
| 81 | \r |
| 82 | static struct miscdevice mmuhack = {\r |
| 83 | MMUHACK_MINOR, DEVICE_NAME, &mmuhack_fops\r |
| 84 | };\r |
| 85 | \r |
| 86 | static int __init mmuhack_init(void)\r |
| 87 | {\r |
| 88 | misc_register(&mmuhack);\r |
| 89 | /*\r |
| 90 | printk("MMSP2 MMU Hack module.\n");\r |
| 91 | */\r |
| 92 | return 0;\r |
| 93 | }\r |
| 94 | \r |
| 95 | static void __exit mmuhack_exit(void)\r |
| 96 | {\r |
| 97 | misc_deregister(&mmuhack);\r |
| 98 | /*\r |
| 99 | printk(KERN_ALERT "MMU Hack module removed.\n");\r |
| 100 | */\r |
| 101 | }\r |
| 102 | \r |
| 103 | module_init(mmuhack_init);\r |
| 104 | module_exit(mmuhack_exit);\r |