start_gcc.S 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664
  1. /*
  2. * Copyright (c) 2020, Shenzhen Academy of Aerospace Technology
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-10-16 Dystopia the first version
  9. */
  10. #define PSR_INIT 0x10C0
  11. #define PREGS 0x80000000
  12. #define IMASK 0x90
  13. #define ICLEAR 0x9c
  14. #define NWINDOWS 8
  15. #define CPU_INTERRUPT_FRAME_SIZE (0x60 + 0x50 + 34 * 4)
  16. #define SPARC_PSR_PIL_MASK 0x00000F00
  17. #define SPARC_PSR_ET_MASK 0x00000020
  18. #define SPARC_PSR_CWP_MASK 0x07
  19. .text
  20. .globl system_vectors
  21. .globl _reset
  22. .globl _context_switch
  23. _reset:
  24. mov %g0, %asr16
  25. mov %g0, %asr17
  26. nop
  27. nop
  28. nop
  29. set PSR_INIT, %g1
  30. mov %g1, %psr
  31. nop
  32. nop
  33. nop
  34. mov %g0, %wim
  35. nop
  36. nop
  37. nop
  38. mov %g0, %g1
  39. mov %g0, %g2
  40. mov %g0, %g3
  41. mov %g0, %g4
  42. mov %g0, %g5
  43. mov %g0, %g6
  44. mov %g0, %g7
  45. mov 0x8, %g1
  46. 1:
  47. mov %g0, %l0
  48. mov %g0, %l1
  49. mov %g0, %l2
  50. mov %g0, %l3
  51. mov %g0, %l4
  52. mov %g0, %l5
  53. mov %g0, %l6
  54. mov %g0, %l7
  55. mov %g0, %i0
  56. mov %g0, %i1
  57. mov %g0, %i2
  58. mov %g0, %i3
  59. mov %g0, %i4
  60. mov %g0, %i5
  61. mov %g0, %i6
  62. mov %g0, %i7
  63. subcc %g1, 1, %g1
  64. save
  65. bne 1b
  66. nop
  67. set 2, %g1
  68. mov %g1, %wim
  69. nop
  70. nop
  71. nop
  72. sethi %hi(system_vectors), %g1
  73. mov %g1, %tbr
  74. nop
  75. nop
  76. nop
  77. set PREGS, %g1
  78. set 0xffff, %g2
  79. st %g2, [%g1 + ICLEAR]
  80. st %g0, [%g1 + IMASK]
  81. set 0x7C47907F, %g2
  82. st %g2, [%g1 + 4]
  83. set PSR_INIT | 0x20, %g1
  84. mov %g1, %psr
  85. nop
  86. nop
  87. nop
  88. set _fsrinit, %g1
  89. ld [%g1], %fsr
  90. nop
  91. nop
  92. nop
  93. set _fpdata, %g1
  94. ldd [%g1], %f0
  95. ldd [%g1], %f2
  96. ldd [%g1], %f4
  97. ldd [%g1], %f6
  98. ldd [%g1], %f8
  99. ldd [%g1], %f10
  100. ldd [%g1], %f12
  101. ldd [%g1], %f14
  102. ldd [%g1], %f16
  103. ldd [%g1], %f18
  104. ldd [%g1], %f20
  105. ldd [%g1], %f22
  106. ldd [%g1], %f24
  107. ldd [%g1], %f26
  108. ldd [%g1], %f28
  109. ldd [%g1], %f30
  110. set __bss_start, %g2
  111. set __bss_end, %g3
  112. mov %g0, %g1
  113. bss_loop:
  114. std %g0, [%g2]
  115. add %g2, 8, %g2
  116. cmp %g2, %g3
  117. bleu,a bss_loop
  118. nop
  119. set 0x401FFF00, %g1
  120. mov %g1, %sp
  121. /* start RT-Thread Kernel */
  122. call rtthread_startup
  123. nop
  124. /*
  125. l0 = psr
  126. l1 = pc
  127. l2 = npc
  128. l3 = tbr
  129. */
  130. .globl _ISR_Handler
  131. _ISR_Handler:
  132. mov %g4, %l4
  133. mov %g5, %l5
  134. mov %wim, %g4
  135. srl %g4, %l0, %g5
  136. cmp %g5, 1
  137. bne dont_do_the_window
  138. nop
  139. srl %g4, 1, %g5
  140. sll %g4, NWINDOWS - 1, %g4
  141. or %g4, %g5, %g4
  142. save
  143. mov %g4, %wim
  144. nop
  145. nop
  146. nop
  147. std %l0, [%sp + 0x00]
  148. std %l2, [%sp + 0x08]
  149. std %l4, [%sp + 0x10]
  150. std %l6, [%sp + 0x18]
  151. std %i0, [%sp + 0x20]
  152. std %i2, [%sp + 0x28]
  153. std %i4, [%sp + 0x30]
  154. std %i6, [%sp + 0x38]
  155. restore
  156. nop
  157. dont_do_the_window:
  158. sub %fp, CPU_INTERRUPT_FRAME_SIZE, %sp
  159. std %l0, [%sp + 0x60]
  160. st %l2, [%sp + 0x68]
  161. st %g1, [%sp + 0x6c]
  162. std %g2, [%sp + 0x70]
  163. std %l4, [%sp + 0x78]
  164. std %g6, [%sp + 0x80]
  165. std %i0, [%sp + 0x88]
  166. std %i2, [%sp + 0x90]
  167. std %i4, [%sp + 0x98]
  168. std %i6, [%sp + 0xA0]
  169. mov %y, %g1
  170. st %g1, [%sp + 0xA8]
  171. st %l6, [%sp + 0xAc]
  172. std %f0, [%sp + 0xB0 + 8 * 0x0]
  173. std %f2, [%sp + 0xB0 + 8 * 0x1]
  174. std %f4, [%sp + 0xB0 + 8 * 0x2]
  175. std %f6, [%sp + 0xB0 + 8 * 0x3]
  176. std %f8, [%sp + 0xB0 + 8 * 0x4]
  177. std %f10, [%sp + 0xB0 + 8 * 0x5]
  178. std %f12, [%sp + 0xB0 + 8 * 0x6]
  179. std %f14, [%sp + 0xB0 + 8 * 0x7]
  180. std %f16, [%sp + 0xB0 + 8 * 0x8]
  181. std %f18, [%sp + 0xB0 + 8 * 0x9]
  182. std %f20, [%sp + 0xB0 + 8 * 0xA]
  183. std %f22, [%sp + 0xB0 + 8 * 0xB]
  184. std %f24, [%sp + 0xB0 + 8 * 0xC]
  185. std %f26, [%sp + 0xB0 + 8 * 0xD]
  186. std %f28, [%sp + 0xB0 + 8 * 0xE]
  187. std %f30, [%sp + 0xB0 + 8 * 0xF]
  188. st %fsr, [%sp + 0xB0 + 8 * 0x10]
  189. mov %l0, %g5
  190. or %g5, SPARC_PSR_PIL_MASK, %g5
  191. wr %g5, SPARC_PSR_ET_MASK, %psr
  192. nop
  193. nop
  194. nop
  195. call rt_interrupt_enter
  196. nop
  197. and %l3, 0x0FF0, %l3
  198. srl %l3, 4, %o0
  199. mov %sp, %o1
  200. call rt_hw_trap
  201. nop
  202. call rt_interrupt_leave
  203. nop
  204. mov %l0, %psr
  205. nop
  206. nop
  207. nop
  208. ld [%sp + 0xA8], %l5
  209. mov %l5, %y
  210. ldd [%sp + 0x60], %l0
  211. ld [%sp + 0x68], %l2
  212. ld [%sp + 0x6c], %g1
  213. ldd [%sp + 0x70], %g2
  214. ldd [%sp + 0x78], %g4
  215. ldd [%sp + 0x80], %g6
  216. ldd [%sp + 0x88], %i0
  217. ldd [%sp + 0x90], %i2
  218. ldd [%sp + 0x98], %i4
  219. ldd [%sp + 0xA0], %i6
  220. ldd [%sp + 0xB0 + 8 * 0x0], %f0
  221. ldd [%sp + 0xB0 + 8 * 0x1], %f2
  222. ldd [%sp + 0xB0 + 8 * 0x2], %f4
  223. ldd [%sp + 0xB0 + 8 * 0x3], %f6
  224. ldd [%sp + 0xB0 + 8 * 0x4], %f8
  225. ldd [%sp + 0xB0 + 8 * 0x5], %f10
  226. ldd [%sp + 0xB0 + 8 * 0x6], %f12
  227. ldd [%sp + 0xB0 + 8 * 0x7], %f14
  228. ldd [%sp + 0xB0 + 8 * 0x8], %f16
  229. ldd [%sp + 0xB0 + 8 * 0x9], %f18
  230. ldd [%sp + 0xB0 + 8 * 0xA], %f20
  231. ldd [%sp + 0xB0 + 8 * 0xB], %f22
  232. ldd [%sp + 0xB0 + 8 * 0xC], %f24
  233. ldd [%sp + 0xB0 + 8 * 0xD], %f26
  234. ldd [%sp + 0xB0 + 8 * 0xE], %f28
  235. ldd [%sp + 0xB0 + 8 * 0xF], %f30
  236. ld [%sp + 0xB0 + 8 * 0x10], %fsr
  237. nop
  238. nop
  239. nop
  240. mov %wim, %l4
  241. add %l0, 1, %l6
  242. and %l6, SPARC_PSR_CWP_MASK, %l6
  243. srl %l4, %l6, %l5
  244. cmp %l5, 1
  245. bne good_task_window
  246. nop
  247. sll %l4, 1, %l5
  248. srl %l4, NWINDOWS - 1, %l4
  249. or %l4, %l5, %l4
  250. mov %l4, %wim
  251. nop
  252. nop
  253. nop
  254. restore
  255. ldd [%sp + 0], %l0 ! Restore window from the stack
  256. ldd [%sp + 8], %l2
  257. ldd [%sp + 16], %l4
  258. ldd [%sp + 24], %l6
  259. ldd [%sp + 32], %i0
  260. ldd [%sp + 40], %i2
  261. ldd [%sp + 48], %i4
  262. ldd [%sp + 56], %i6
  263. save
  264. good_task_window:
  265. set rt_thread_switch_interrupt_flag, %l4
  266. ld [%l4], %l5
  267. cmp %l5, 1
  268. be rt_hw_context_switch_interrupt_do
  269. nop
  270. mov %l0, %psr
  271. nop
  272. nop
  273. nop
  274. jmp %l1
  275. rett %l2
  276. rt_hw_context_switch_interrupt_do:
  277. st %g0, [%l4]
  278. sub %fp, 0x20, %sp
  279. std %g0, [%sp + 0x00]
  280. std %g2, [%sp + 0x08]
  281. std %g4, [%sp + 0x10]
  282. std %g6, [%sp + 0x18]
  283. mov %sp, %g3
  284. mov %l1, %g4
  285. mov %l2, %g5
  286. mov %l0, %g6
  287. mov %wim, %g7
  288. mov %g0, %wim
  289. nop
  290. nop
  291. nop
  292. set 0xFFFFFFF8, %g1
  293. and %g1, %g6, %g1
  294. mov %g1, %psr
  295. nop
  296. nop
  297. nop
  298. mov %g0, %g1
  299. save_loop:
  300. save
  301. sub %g3, 0x40, %g3
  302. std %l0, [%g3 + 0x00]
  303. std %l2, [%g3 + 0x08]
  304. std %l4, [%g3 + 0x10]
  305. std %l6, [%g3 + 0x18]
  306. std %i0, [%g3 + 0x20]
  307. std %i2, [%g3 + 0x28]
  308. std %i4, [%g3 + 0x30]
  309. std %i6, [%g3 + 0x38]
  310. inc %g1
  311. cmp %g1, NWINDOWS
  312. bne save_loop
  313. nop
  314. sub %g3, 0x88, %g3
  315. std %f0, [%g3 + 0x00]
  316. std %f2, [%g3 + 0x08]
  317. std %f4, [%g3 + 0x10]
  318. std %f6, [%g3 + 0x18]
  319. std %f8, [%g3 + 0x20]
  320. std %f10, [%g3 + 0x28]
  321. std %f12, [%g3 + 0x30]
  322. std %f14, [%g3 + 0x38]
  323. std %f16, [%g3 + 0x40]
  324. std %f18, [%g3 + 0x48]
  325. std %f20, [%g3 + 0x50]
  326. std %f22, [%g3 + 0x58]
  327. std %f24, [%g3 + 0x60]
  328. std %f26, [%g3 + 0x68]
  329. std %f28, [%g3 + 0x70]
  330. std %f30, [%g3 + 0x78]
  331. mov %y, %g1
  332. st %g1, [%g3 + 0x80]
  333. st %fsr, [%g3 + 0x84]
  334. sub %g3, 0x10, %g3
  335. std %g4, [%g3 + 0x00]
  336. std %g6, [%g3 + 0x08]
  337. set rt_interrupt_from_thread, %g1
  338. ld [%g1], %g2
  339. st %g3, [%g2]
  340. set rt_interrupt_to_thread, %g1
  341. ld [%g1], %g1
  342. ld [%g1], %g3
  343. ldd [%g3 + 0x00], %g4
  344. ldd [%g3 + 0x08], %g6
  345. add %g3, 0x10, %g3
  346. ldd [%g3 + 0x00], %f0
  347. ldd [%g3 + 0x08], %f2
  348. ldd [%g3 + 0x10], %f4
  349. ldd [%g3 + 0x18], %f6
  350. ldd [%g3 + 0x20], %f8
  351. ldd [%g3 + 0x28], %f10
  352. ldd [%g3 + 0x30], %f12
  353. ldd [%g3 + 0x38], %f14
  354. ldd [%g3 + 0x40], %f16
  355. ldd [%g3 + 0x48], %f18
  356. ldd [%g3 + 0x50], %f20
  357. ldd [%g3 + 0x58], %f22
  358. ldd [%g3 + 0x60], %f24
  359. ldd [%g3 + 0x68], %f26
  360. ldd [%g3 + 0x70], %f28
  361. ldd [%g3 + 0x78], %f30
  362. ld [%g3 + 0x80], %g1
  363. mov %g1, %y
  364. ld [%g3 + 0x84], %fsr
  365. add %g3, 0x88, %g3
  366. set NWINDOWS - 1, %g1
  367. or %g1, %g6, %g1
  368. mov %g1, %psr
  369. nop
  370. nop
  371. nop
  372. mov %g0, %g1
  373. restore_loop:
  374. restore
  375. ldd [%g3 + 0x00], %l0
  376. ldd [%g3 + 0x08], %l2
  377. ldd [%g3 + 0x10], %l4
  378. ldd [%g3 + 0x18], %l6
  379. ldd [%g3 + 0x20], %i0
  380. ldd [%g3 + 0x28], %i2
  381. ldd [%g3 + 0x30], %i4
  382. ldd [%g3 + 0x38], %i6
  383. add %g3, 0x40, %g3
  384. inc %g1
  385. cmp %g1, NWINDOWS
  386. bne restore_loop
  387. nop
  388. mov %g6, %psr
  389. nop
  390. nop
  391. nop
  392. mov %g7, %wim
  393. nop
  394. nop
  395. nop
  396. mov %g4, %l1
  397. mov %g5, %l2
  398. mov %g3, %sp
  399. ldd [%sp + 0x00], %g0
  400. ldd [%sp + 0x08], %g2
  401. ldd [%sp + 0x10], %g4
  402. ldd [%sp + 0x18], %g6
  403. add %sp, 0x20, %fp
  404. jmp %l1
  405. rett %l2
  406. /*
  407. l0 = psr
  408. l1 = pc
  409. l2 = npc
  410. l3 = tbr
  411. */
  412. _context_switch:
  413. mov %l2, %l1
  414. add %l2, 4, %l2
  415. mov %g4, %l4
  416. mov %g5, %l5
  417. mov %wim, %g4
  418. srl %g4, %l0, %g5
  419. cmp %g5, 1
  420. bne good_window
  421. nop
  422. srl %g4, 1, %g5
  423. sll %g4, NWINDOWS - 1, %g4
  424. or %g4, %g5, %g4
  425. save
  426. mov %g4, %wim
  427. nop
  428. nop
  429. nop
  430. std %l0, [%sp + 0x00]
  431. std %l2, [%sp + 0x08]
  432. std %l4, [%sp + 0x10]
  433. std %l6, [%sp + 0x18]
  434. std %i0, [%sp + 0x20]
  435. std %i2, [%sp + 0x28]
  436. std %i4, [%sp + 0x30]
  437. std %i6, [%sp + 0x38]
  438. restore
  439. nop
  440. good_window:
  441. and %l3, 0x0FF0, %l3
  442. srl %l3, 4, %l4
  443. cmp %l4, 0x82
  444. bne switch_to
  445. nop
  446. sub %fp, 0x20, %sp
  447. std %g0, [%sp + 0x00]
  448. std %g2, [%sp + 0x08]
  449. std %g4, [%sp + 0x10]
  450. std %g6, [%sp + 0x18]
  451. mov %sp, %g3
  452. mov %l1, %g4
  453. mov %l2, %g5
  454. mov %l0, %g6
  455. mov %wim, %g7
  456. mov %g0, %wim
  457. nop
  458. nop
  459. nop
  460. set 0xFFFFFFF8, %g1
  461. and %g1, %g6, %g1
  462. mov %g1, %psr
  463. nop
  464. nop
  465. nop
  466. mov %g0, %g1
  467. save_window:
  468. save
  469. sub %g3, 0x40, %g3
  470. std %l0, [%g3 + 0x00]
  471. std %l2, [%g3 + 0x08]
  472. std %l4, [%g3 + 0x10]
  473. std %l6, [%g3 + 0x18]
  474. std %i0, [%g3 + 0x20]
  475. std %i2, [%g3 + 0x28]
  476. std %i4, [%g3 + 0x30]
  477. std %i6, [%g3 + 0x38]
  478. inc %g1
  479. cmp %g1, NWINDOWS
  480. bne save_window
  481. nop
  482. sub %g3, 0x88, %g3
  483. std %f0, [%g3 + 0x00]
  484. std %f2, [%g3 + 0x08]
  485. std %f4, [%g3 + 0x10]
  486. std %f6, [%g3 + 0x18]
  487. std %f8, [%g3 + 0x20]
  488. std %f10, [%g3 + 0x28]
  489. std %f12, [%g3 + 0x30]
  490. std %f14, [%g3 + 0x38]
  491. std %f16, [%g3 + 0x40]
  492. std %f18, [%g3 + 0x48]
  493. std %f20, [%g3 + 0x50]
  494. std %f22, [%g3 + 0x58]
  495. std %f24, [%g3 + 0x60]
  496. std %f26, [%g3 + 0x68]
  497. std %f28, [%g3 + 0x70]
  498. std %f30, [%g3 + 0x78]
  499. mov %y, %g1
  500. st %g1, [%g3 + 0x80]
  501. st %fsr, [%g3 + 0x84]
  502. sub %g3, 0x10, %g3
  503. std %g4, [%g3 + 0x00]
  504. std %g6, [%g3 + 0x08]
  505. mov %g6, %psr
  506. nop
  507. nop
  508. nop
  509. st %g3, [%i0]
  510. switch_to:
  511. mov %g0, %wim
  512. nop
  513. nop
  514. nop
  515. ld [%i1], %g3
  516. ldd [%g3 + 0x00], %g4
  517. ldd [%g3 + 0x08], %g6
  518. add %g3, 0x10, %g3
  519. ldd [%g3 + 0x00], %f0
  520. ldd [%g3 + 0x08], %f2
  521. ldd [%g3 + 0x10], %f4
  522. ldd [%g3 + 0x18], %f6
  523. ldd [%g3 + 0x20], %f8
  524. ldd [%g3 + 0x28], %f10
  525. ldd [%g3 + 0x30], %f12
  526. ldd [%g3 + 0x38], %f14
  527. ldd [%g3 + 0x40], %f16
  528. ldd [%g3 + 0x48], %f18
  529. ldd [%g3 + 0x50], %f20
  530. ldd [%g3 + 0x58], %f22
  531. ldd [%g3 + 0x60], %f24
  532. ldd [%g3 + 0x68], %f26
  533. ldd [%g3 + 0x70], %f28
  534. ldd [%g3 + 0x78], %f30
  535. ld [%g3 + 0x80], %g1
  536. mov %g1, %y
  537. ld [%g3 + 0x84], %fsr
  538. add %g3, 0x88, %g3
  539. set NWINDOWS - 1, %g1
  540. or %g1, %g6, %g1
  541. mov %g1, %psr
  542. nop
  543. nop
  544. nop
  545. mov %g0, %g1
  546. restore_window:
  547. restore
  548. ldd [%g3 + 0x00], %l0
  549. ldd [%g3 + 0x08], %l2
  550. ldd [%g3 + 0x10], %l4
  551. ldd [%g3 + 0x18], %l6
  552. ldd [%g3 + 0x20], %i0
  553. ldd [%g3 + 0x28], %i2
  554. ldd [%g3 + 0x30], %i4
  555. ldd [%g3 + 0x38], %i6
  556. add %g3, 0x40, %g3
  557. inc %g1
  558. cmp %g1, NWINDOWS
  559. bne restore_window
  560. nop
  561. mov %g6, %psr
  562. nop
  563. nop
  564. nop
  565. mov %g7, %wim
  566. nop
  567. nop
  568. nop
  569. mov %g4, %l1
  570. mov %g5, %l2
  571. mov %g3, %sp
  572. ldd [%sp + 0x00], %g0
  573. ldd [%sp + 0x08], %g2
  574. ldd [%sp + 0x10], %g4
  575. ldd [%sp + 0x18], %g6
  576. add %sp, 0x20, %fp
  577. jmp %l1
  578. rett %l2
  579. .data
  580. .align 8
  581. _fpdata:
  582. .word 0, 0
  583. _fsrinit:
  584. .word 0