Guest User

Untitled

a guest
Jun 23rd, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.79 KB | None | 0 0
  1. #include <asm/uaccess.h>
  2. #include <asm/cacheflush.h>
  3. #include <asm/tlbflush.h>
  4. #include <asm/io.h>
  5. #include <linux/module.h>
  6. #include <linux/fs.h>
  7. #include <linux/cdev.h>
  8. #include <linux/device.h>
  9. #include "hboot.h"
  10. #define CTRL_DEVNAME "hbootctrl"
  11. static int dev_major;
  12.  
  13. void v7_flush_kern_cache_all(void);//c0045dd4
  14. void activate_emu_uart(void);
  15.  
  16. // will _never_ return
  17. int __attribute__((__naked__)) do_branch(void *bootlist, uint32_t bootsize, uint32_t new_ttbl, void *func) {
  18. __asm__ volatile (
  19. "stmfd sp!, {r0-r3}\n"
  20. );
  21.  
  22. activate_emu_uart();
  23. __raw_writel(0x02, 0xd9020054); //reset uart
  24. while (!(__raw_readl(0xd9020058)&1));
  25. __raw_writel(0x80, 0xd902000c); // setup divisors
  26. __raw_writel(0x1a, 0xd9020000);
  27. __raw_writel(0x00, 0xd9020004);
  28. __raw_writel(0x03, 0xd902000c); // 8 data bits
  29. __raw_writel(0x00, 0xd9020020);
  30.  
  31. __raw_writel(__raw_readl(0xD805602C)|2, 0xD805602C);//sdma reset
  32. while (__raw_readl(0xD8056028)!=1);
  33.  
  34. local_flush_tlb_all();
  35. v7_flush_kern_cache_all();
  36. __asm__ volatile (
  37. "mov r0, #0x00\n"
  38. "mcr p15, 0, r0, c7, c5, 0\n"
  39. "mcr p15, 0, r0, c7, c5, 6\n"
  40. "mrc p15, 0, r0, c1, c0, 0\n"
  41. "bic r0, r0, #0x1800\n" //-i -z
  42. "bic r0, r0, #0x0006\n" //-c -a
  43. "mcr p15, 0, r0, c1, c0, 0\n"
  44. "mrc p15, 0, r0, c1, c0, 1\n"
  45. "bic r0, #0x02\n"
  46. "mcr p15, 0, r0, c1, c0, 1\n"
  47. "ldmfd sp!, {r0-r3}\n"
  48. "bx r3\n"
  49. );
  50. return 0;
  51. }
  52.  
  53. static void l1_map(uint32_t *table, uint32_t phys, uint32_t virt, size_t sects, uint32_t flags) {
  54. uint32_t physbase, virtbase;
  55.  
  56. physbase = phys >> 20;
  57. virtbase = virt >> 20;
  58. while (sects-- > 0) {
  59. table[virtbase++] = (physbase++ << 20) | flags;
  60. }
  61. }
  62.  
  63. #define L1_NORMAL_MAPPING (PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_WB)
  64. #define L1_DEVICE_MAPPING (PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_UNCACHED)
  65. void build_l1_table(uint32_t *table) {
  66. memset(table, 0, 4*4096);
  67. l1_map(table, PHYS_OFFSET, PHYS_OFFSET, 256-12, L1_NORMAL_MAPPING);
  68. l1_map(table, PHYS_OFFSET, PAGE_OFFSET, 256-12, L1_NORMAL_MAPPING);
  69. }
  70.  
  71. int hboot_boot(int handle) {
  72. bootfunc_t boot_entry;
  73. uint32_t bootsize, listsize;
  74. void *bootlist;
  75. uint32_t l1_mem, *l1_table;
  76.  
  77. l1_mem = get_high_pages(2);
  78. if (l1_mem == 0) {
  79. printk("Failed to allocate new l1 table\n");
  80. return -ENOMEM;
  81. }
  82. if (l1_mem & 0x3fff) {
  83. // l1_table = (uint32_t*)(((l1_mem >> 14) + 1) << 14);
  84. printk("unaligned l1 table\n");
  85. free_high_pages((void*)l1_mem, 2);
  86. return -EINVAL;
  87. } else {
  88. l1_table = (uint32_t*)l1_mem;
  89. }
  90. build_l1_table(l1_table);
  91.  
  92. boot_entry = get_bootentry(&bootsize, handle);
  93. if (boot_entry == NULL) {
  94. return -EINVAL;
  95. }
  96. bootlist = get_bootlist(&listsize, handle);
  97. if (bootlist == NULL) {
  98. return -ENOMEM;
  99. }
  100. preempt_disable();
  101. local_irq_disable();
  102. local_fiq_disable();
  103. do_branch(bootlist, listsize, virt_to_phys(l1_table), boot_entry);
  104.  
  105. /* not a chance */
  106. #if 0
  107. set_ttbl_base(l1_old);
  108. local_fiq_enable();
  109. local_irq_enable();
  110. preempt_enable();
  111. #else
  112. while (1);
  113. #endif
  114. return -EBUSY;
  115. }
  116.  
  117. static int hbootctrl_open(struct inode *inode, struct file *file);
  118. static int hbootctrl_release(struct inode *inode, struct file *file);
  119. static int hbootctrl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
  120. static int hbootctrl_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos);
  121.  
  122. static struct file_operations hbootctrl_ops = {
  123. .owner = THIS_MODULE,
  124. .open = hbootctrl_open,
  125. .release = hbootctrl_release,
  126. .ioctl = hbootctrl_ioctl,
  127. .write = hbootctrl_write,
  128.  
  129. };
  130.  
  131. static int hbootctrl_open(struct inode *inode, struct file *file) {
  132. printk(KERN_INFO CTRL_DEVNAME ": `open' stub called\n");
  133. return 0;
  134. }
  135.  
  136. static int hbootctrl_release(struct inode *inode, struct file *file) {
  137. printk(KERN_INFO CTRL_DEVNAME ": `releae' stub called\n");
  138. return 0;
  139. }
  140.  
  141. static int hbootctrl_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) {
  142. int ret;
  143. int handle;
  144. struct hboot_buffer_req buf_req;
  145.  
  146. ret = 0;
  147. switch (cmd) {
  148. case HBOOT_ALLOCATE_BUFFER:
  149. if (copy_from_user((void*)&buf_req, (void*)arg, sizeof(struct hboot_buffer_req)) != 0) {
  150. printk(KERN_WARNING CTRL_DEVNAME ": failed to copy buffer request\n");
  151. return -EINVAL;
  152. }
  153. ret = allocate_buffer(buf_req.tag, buf_req.type, buf_req.attrs, buf_req.size, buf_req.rest);
  154. break;
  155. case HBOOT_FREE_BUFFER:
  156. handle = (int)arg;
  157. ret = free_buffer(handle);
  158. break;
  159. case HBOOT_SELECT_BUFFER:
  160. handle = (int)arg;
  161. ret = select_buffer(handle);
  162. if (ret >= 0) {
  163. file->f_pos = 0;
  164. }
  165. break;
  166. case HBOOT_BOOT:
  167. handle = (int)arg;
  168. ret = hboot_boot(handle);
  169. break;
  170. default:
  171. printk(KERN_INFO CTRL_DEVNAME ": unknown ioctl\n");
  172. ret = -EINVAL;
  173. break;
  174. }
  175. return ret;
  176. }
  177.  
  178. static int hbootctrl_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) {
  179. return buffer_append_userdata(buf, count, ppos);
  180. }
  181.  
  182. int __init hboot_init(void) {
  183. int ret;
  184.  
  185. ret = buffers_init();
  186. if (ret < 0) {
  187. printk(KERN_WARNING CTRL_DEVNAME ": Failed to initialize buffers table\n");
  188. return ret;
  189. }
  190.  
  191. ret = register_chrdev(0, CTRL_DEVNAME, &hbootctrl_ops);
  192. if (ret < 0) {
  193. printk(KERN_WARNING CTRL_DEVNAME ": Failed to register dev\n");
  194. buffers_destroy();
  195. return ret;
  196. }
  197. dev_major = ret;
  198.  
  199. if (ret < 0) {
  200. printk(KERN_WARNING CTRL_DEVNAME ": Failed to create dev\n");
  201. unregister_chrdev(dev_major, CTRL_DEVNAME);
  202. buffers_destroy();
  203. return ret;
  204. }
  205.  
  206. printk(KERN_INFO CTRL_DEVNAME ": Successfully registered dev\n");
  207. return 0;
  208. }
  209.  
  210. void __exit hboot_exit(void) {
  211. if (dev_major) {
  212. buffers_destroy();
  213. unregister_chrdev(dev_major, CTRL_DEVNAME);
  214. }
  215. return;
  216. }
  217.  
  218. module_init(hboot_init);
  219. module_exit(hboot_exit);
Add Comment
Please, Sign In to add comment