armsse.c 60 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739
  1. /*
  2. * Arm SSE (Subsystems for Embedded): IoTKit
  3. *
  4. * Copyright (c) 2018 Linaro Limited
  5. * Written by Peter Maydell
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 or
  9. * (at your option) any later version.
  10. */
  11. #include "qemu/osdep.h"
  12. #include "qemu/log.h"
  13. #include "qemu/module.h"
  14. #include "qemu/bitops.h"
  15. #include "qemu/units.h"
  16. #include "qapi/error.h"
  17. #include "trace.h"
  18. #include "hw/sysbus.h"
  19. #include "migration/vmstate.h"
  20. #include "hw/registerfields.h"
  21. #include "hw/arm/armsse.h"
  22. #include "hw/arm/armsse-version.h"
  23. #include "hw/arm/boot.h"
  24. #include "hw/irq.h"
  25. #include "hw/qdev-clock.h"
  26. /*
  27. * The SSE-300 puts some devices in different places to the
  28. * SSE-200 (and original IoTKit). We use an array of these structs
  29. * to define how each variant lays out these devices. (Parts of the
  30. * SoC that are the same for all variants aren't handled via these
  31. * data structures.)
  32. */
  33. #define NO_IRQ -1
  34. #define NO_PPC -1
  35. /*
  36. * Special values for ARMSSEDeviceInfo::irq to indicate that this
  37. * device uses one of the inputs to the OR gate that feeds into the
  38. * CPU NMI input.
  39. */
  40. #define NMI_0 10000
  41. #define NMI_1 10001
  42. typedef struct ARMSSEDeviceInfo {
  43. const char *name; /* name to use for the QOM object; NULL terminates list */
  44. const char *type; /* QOM type name */
  45. unsigned int index; /* Which of the N devices of this type is this ? */
  46. hwaddr addr;
  47. hwaddr size; /* only needed for TYPE_UNIMPLEMENTED_DEVICE */
  48. int ppc; /* Index of APB PPC this device is wired up to, or NO_PPC */
  49. int ppc_port; /* Port number of this device on the PPC */
  50. int irq; /* NO_IRQ, or 0..NUM_SSE_IRQS-1, or NMI_0 or NMI_1 */
  51. bool slowclk; /* true if device uses the slow 32KHz clock */
  52. } ARMSSEDeviceInfo;
  53. struct ARMSSEInfo {
  54. const char *name;
  55. const char *cpu_type;
  56. uint32_t sse_version;
  57. int sram_banks;
  58. uint32_t sram_bank_base;
  59. int num_cpus;
  60. uint32_t sys_version;
  61. uint32_t iidr;
  62. uint32_t cpuwait_rst;
  63. bool has_mhus;
  64. bool has_cachectrl;
  65. bool has_cpusecctrl;
  66. bool has_cpuid;
  67. bool has_cpu_pwrctrl;
  68. bool has_sse_counter;
  69. bool has_tcms;
  70. uint8_t props_count;
  71. const Property *props;
  72. const ARMSSEDeviceInfo *devinfo;
  73. const bool *irq_is_common;
  74. };
  75. static const Property iotkit_properties[] = {
  76. DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
  77. MemoryRegion *),
  78. DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
  79. DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
  80. DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
  81. DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
  82. DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], true),
  83. DEFINE_PROP_UINT32("CPU0_MPU_NS", ARMSSE, cpu_mpu_ns[0], 8),
  84. DEFINE_PROP_UINT32("CPU0_MPU_S", ARMSSE, cpu_mpu_s[0], 8),
  85. };
  86. static const Property sse200_properties[] = {
  87. DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
  88. MemoryRegion *),
  89. DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
  90. DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 15),
  91. DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
  92. DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], false),
  93. DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], false),
  94. DEFINE_PROP_BOOL("CPU1_FPU", ARMSSE, cpu_fpu[1], true),
  95. DEFINE_PROP_BOOL("CPU1_DSP", ARMSSE, cpu_dsp[1], true),
  96. DEFINE_PROP_UINT32("CPU0_MPU_NS", ARMSSE, cpu_mpu_ns[0], 8),
  97. DEFINE_PROP_UINT32("CPU0_MPU_S", ARMSSE, cpu_mpu_s[0], 8),
  98. DEFINE_PROP_UINT32("CPU1_MPU_NS", ARMSSE, cpu_mpu_ns[1], 8),
  99. DEFINE_PROP_UINT32("CPU1_MPU_S", ARMSSE, cpu_mpu_s[1], 8),
  100. };
  101. static const Property sse300_properties[] = {
  102. DEFINE_PROP_LINK("memory", ARMSSE, board_memory, TYPE_MEMORY_REGION,
  103. MemoryRegion *),
  104. DEFINE_PROP_UINT32("EXP_NUMIRQ", ARMSSE, exp_numirq, 64),
  105. DEFINE_PROP_UINT32("SRAM_ADDR_WIDTH", ARMSSE, sram_addr_width, 18),
  106. DEFINE_PROP_UINT32("init-svtor", ARMSSE, init_svtor, 0x10000000),
  107. DEFINE_PROP_BOOL("CPU0_FPU", ARMSSE, cpu_fpu[0], true),
  108. DEFINE_PROP_BOOL("CPU0_DSP", ARMSSE, cpu_dsp[0], true),
  109. DEFINE_PROP_UINT32("CPU0_MPU_NS", ARMSSE, cpu_mpu_ns[0], 8),
  110. DEFINE_PROP_UINT32("CPU0_MPU_S", ARMSSE, cpu_mpu_s[0], 8),
  111. };
  112. static const ARMSSEDeviceInfo iotkit_devices[] = {
  113. {
  114. .name = "timer0",
  115. .type = TYPE_CMSDK_APB_TIMER,
  116. .index = 0,
  117. .addr = 0x40000000,
  118. .ppc = 0,
  119. .ppc_port = 0,
  120. .irq = 3,
  121. },
  122. {
  123. .name = "timer1",
  124. .type = TYPE_CMSDK_APB_TIMER,
  125. .index = 1,
  126. .addr = 0x40001000,
  127. .ppc = 0,
  128. .ppc_port = 1,
  129. .irq = 4,
  130. },
  131. {
  132. .name = "s32ktimer",
  133. .type = TYPE_CMSDK_APB_TIMER,
  134. .index = 2,
  135. .addr = 0x4002f000,
  136. .ppc = 1,
  137. .ppc_port = 0,
  138. .irq = 2,
  139. .slowclk = true,
  140. },
  141. {
  142. .name = "dualtimer",
  143. .type = TYPE_CMSDK_APB_DUALTIMER,
  144. .index = 0,
  145. .addr = 0x40002000,
  146. .ppc = 0,
  147. .ppc_port = 2,
  148. .irq = 5,
  149. },
  150. {
  151. .name = "s32kwatchdog",
  152. .type = TYPE_CMSDK_APB_WATCHDOG,
  153. .index = 0,
  154. .addr = 0x5002e000,
  155. .ppc = NO_PPC,
  156. .irq = NMI_0,
  157. .slowclk = true,
  158. },
  159. {
  160. .name = "nswatchdog",
  161. .type = TYPE_CMSDK_APB_WATCHDOG,
  162. .index = 1,
  163. .addr = 0x40081000,
  164. .ppc = NO_PPC,
  165. .irq = 1,
  166. },
  167. {
  168. .name = "swatchdog",
  169. .type = TYPE_CMSDK_APB_WATCHDOG,
  170. .index = 2,
  171. .addr = 0x50081000,
  172. .ppc = NO_PPC,
  173. .irq = NMI_1,
  174. },
  175. {
  176. .name = "armsse-sysinfo",
  177. .type = TYPE_IOTKIT_SYSINFO,
  178. .index = 0,
  179. .addr = 0x40020000,
  180. .ppc = NO_PPC,
  181. .irq = NO_IRQ,
  182. },
  183. {
  184. .name = "armsse-sysctl",
  185. .type = TYPE_IOTKIT_SYSCTL,
  186. .index = 0,
  187. .addr = 0x50021000,
  188. .ppc = NO_PPC,
  189. .irq = NO_IRQ,
  190. },
  191. {
  192. .name = NULL,
  193. }
  194. };
  195. static const ARMSSEDeviceInfo sse200_devices[] = {
  196. {
  197. .name = "timer0",
  198. .type = TYPE_CMSDK_APB_TIMER,
  199. .index = 0,
  200. .addr = 0x40000000,
  201. .ppc = 0,
  202. .ppc_port = 0,
  203. .irq = 3,
  204. },
  205. {
  206. .name = "timer1",
  207. .type = TYPE_CMSDK_APB_TIMER,
  208. .index = 1,
  209. .addr = 0x40001000,
  210. .ppc = 0,
  211. .ppc_port = 1,
  212. .irq = 4,
  213. },
  214. {
  215. .name = "s32ktimer",
  216. .type = TYPE_CMSDK_APB_TIMER,
  217. .index = 2,
  218. .addr = 0x4002f000,
  219. .ppc = 1,
  220. .ppc_port = 0,
  221. .irq = 2,
  222. .slowclk = true,
  223. },
  224. {
  225. .name = "dualtimer",
  226. .type = TYPE_CMSDK_APB_DUALTIMER,
  227. .index = 0,
  228. .addr = 0x40002000,
  229. .ppc = 0,
  230. .ppc_port = 2,
  231. .irq = 5,
  232. },
  233. {
  234. .name = "s32kwatchdog",
  235. .type = TYPE_CMSDK_APB_WATCHDOG,
  236. .index = 0,
  237. .addr = 0x5002e000,
  238. .ppc = NO_PPC,
  239. .irq = NMI_0,
  240. .slowclk = true,
  241. },
  242. {
  243. .name = "nswatchdog",
  244. .type = TYPE_CMSDK_APB_WATCHDOG,
  245. .index = 1,
  246. .addr = 0x40081000,
  247. .ppc = NO_PPC,
  248. .irq = 1,
  249. },
  250. {
  251. .name = "swatchdog",
  252. .type = TYPE_CMSDK_APB_WATCHDOG,
  253. .index = 2,
  254. .addr = 0x50081000,
  255. .ppc = NO_PPC,
  256. .irq = NMI_1,
  257. },
  258. {
  259. .name = "armsse-sysinfo",
  260. .type = TYPE_IOTKIT_SYSINFO,
  261. .index = 0,
  262. .addr = 0x40020000,
  263. .ppc = NO_PPC,
  264. .irq = NO_IRQ,
  265. },
  266. {
  267. .name = "armsse-sysctl",
  268. .type = TYPE_IOTKIT_SYSCTL,
  269. .index = 0,
  270. .addr = 0x50021000,
  271. .ppc = NO_PPC,
  272. .irq = NO_IRQ,
  273. },
  274. {
  275. .name = "CPU0CORE_PPU",
  276. .type = TYPE_UNIMPLEMENTED_DEVICE,
  277. .index = 0,
  278. .addr = 0x50023000,
  279. .size = 0x1000,
  280. .ppc = NO_PPC,
  281. .irq = NO_IRQ,
  282. },
  283. {
  284. .name = "CPU1CORE_PPU",
  285. .type = TYPE_UNIMPLEMENTED_DEVICE,
  286. .index = 1,
  287. .addr = 0x50025000,
  288. .size = 0x1000,
  289. .ppc = NO_PPC,
  290. .irq = NO_IRQ,
  291. },
  292. {
  293. .name = "DBG_PPU",
  294. .type = TYPE_UNIMPLEMENTED_DEVICE,
  295. .index = 2,
  296. .addr = 0x50029000,
  297. .size = 0x1000,
  298. .ppc = NO_PPC,
  299. .irq = NO_IRQ,
  300. },
  301. {
  302. .name = "RAM0_PPU",
  303. .type = TYPE_UNIMPLEMENTED_DEVICE,
  304. .index = 3,
  305. .addr = 0x5002a000,
  306. .size = 0x1000,
  307. .ppc = NO_PPC,
  308. .irq = NO_IRQ,
  309. },
  310. {
  311. .name = "RAM1_PPU",
  312. .type = TYPE_UNIMPLEMENTED_DEVICE,
  313. .index = 4,
  314. .addr = 0x5002b000,
  315. .size = 0x1000,
  316. .ppc = NO_PPC,
  317. .irq = NO_IRQ,
  318. },
  319. {
  320. .name = "RAM2_PPU",
  321. .type = TYPE_UNIMPLEMENTED_DEVICE,
  322. .index = 5,
  323. .addr = 0x5002c000,
  324. .size = 0x1000,
  325. .ppc = NO_PPC,
  326. .irq = NO_IRQ,
  327. },
  328. {
  329. .name = "RAM3_PPU",
  330. .type = TYPE_UNIMPLEMENTED_DEVICE,
  331. .index = 6,
  332. .addr = 0x5002d000,
  333. .size = 0x1000,
  334. .ppc = NO_PPC,
  335. .irq = NO_IRQ,
  336. },
  337. {
  338. .name = "SYS_PPU",
  339. .type = TYPE_UNIMPLEMENTED_DEVICE,
  340. .index = 7,
  341. .addr = 0x50022000,
  342. .size = 0x1000,
  343. .ppc = NO_PPC,
  344. .irq = NO_IRQ,
  345. },
  346. {
  347. .name = NULL,
  348. }
  349. };
  350. static const ARMSSEDeviceInfo sse300_devices[] = {
  351. {
  352. .name = "timer0",
  353. .type = TYPE_SSE_TIMER,
  354. .index = 0,
  355. .addr = 0x48000000,
  356. .ppc = 0,
  357. .ppc_port = 0,
  358. .irq = 3,
  359. },
  360. {
  361. .name = "timer1",
  362. .type = TYPE_SSE_TIMER,
  363. .index = 1,
  364. .addr = 0x48001000,
  365. .ppc = 0,
  366. .ppc_port = 1,
  367. .irq = 4,
  368. },
  369. {
  370. .name = "timer2",
  371. .type = TYPE_SSE_TIMER,
  372. .index = 2,
  373. .addr = 0x48002000,
  374. .ppc = 0,
  375. .ppc_port = 2,
  376. .irq = 5,
  377. },
  378. {
  379. .name = "timer3",
  380. .type = TYPE_SSE_TIMER,
  381. .index = 3,
  382. .addr = 0x48003000,
  383. .ppc = 0,
  384. .ppc_port = 5,
  385. .irq = 27,
  386. },
  387. {
  388. .name = "s32ktimer",
  389. .type = TYPE_CMSDK_APB_TIMER,
  390. .index = 0,
  391. .addr = 0x4802f000,
  392. .ppc = 1,
  393. .ppc_port = 0,
  394. .irq = 2,
  395. .slowclk = true,
  396. },
  397. {
  398. .name = "s32kwatchdog",
  399. .type = TYPE_CMSDK_APB_WATCHDOG,
  400. .index = 0,
  401. .addr = 0x4802e000,
  402. .ppc = NO_PPC,
  403. .irq = NMI_0,
  404. .slowclk = true,
  405. },
  406. {
  407. .name = "watchdog",
  408. .type = TYPE_UNIMPLEMENTED_DEVICE,
  409. .index = 0,
  410. .addr = 0x48040000,
  411. .size = 0x2000,
  412. .ppc = NO_PPC,
  413. .irq = NO_IRQ,
  414. },
  415. {
  416. .name = "armsse-sysinfo",
  417. .type = TYPE_IOTKIT_SYSINFO,
  418. .index = 0,
  419. .addr = 0x48020000,
  420. .ppc = NO_PPC,
  421. .irq = NO_IRQ,
  422. },
  423. {
  424. .name = "armsse-sysctl",
  425. .type = TYPE_IOTKIT_SYSCTL,
  426. .index = 0,
  427. .addr = 0x58021000,
  428. .ppc = NO_PPC,
  429. .irq = NO_IRQ,
  430. },
  431. {
  432. .name = "SYS_PPU",
  433. .type = TYPE_UNIMPLEMENTED_DEVICE,
  434. .index = 1,
  435. .addr = 0x58022000,
  436. .size = 0x1000,
  437. .ppc = NO_PPC,
  438. .irq = NO_IRQ,
  439. },
  440. {
  441. .name = "CPU0CORE_PPU",
  442. .type = TYPE_UNIMPLEMENTED_DEVICE,
  443. .index = 2,
  444. .addr = 0x50023000,
  445. .size = 0x1000,
  446. .ppc = NO_PPC,
  447. .irq = NO_IRQ,
  448. },
  449. {
  450. .name = "MGMT_PPU",
  451. .type = TYPE_UNIMPLEMENTED_DEVICE,
  452. .index = 3,
  453. .addr = 0x50028000,
  454. .size = 0x1000,
  455. .ppc = NO_PPC,
  456. .irq = NO_IRQ,
  457. },
  458. {
  459. .name = "DEBUG_PPU",
  460. .type = TYPE_UNIMPLEMENTED_DEVICE,
  461. .index = 4,
  462. .addr = 0x50029000,
  463. .size = 0x1000,
  464. .ppc = NO_PPC,
  465. .irq = NO_IRQ,
  466. },
  467. {
  468. .name = NULL,
  469. }
  470. };
  471. /* Is internal IRQ n shared between CPUs in a multi-core SSE ? */
  472. static const bool sse200_irq_is_common[32] = {
  473. [0 ... 5] = true,
  474. /* 6, 7: per-CPU MHU interrupts */
  475. [8 ... 12] = true,
  476. /* 13: per-CPU icache interrupt */
  477. /* 14: reserved */
  478. [15 ... 20] = true,
  479. /* 21: reserved */
  480. [22 ... 26] = true,
  481. /* 27: reserved */
  482. /* 28, 29: per-CPU CTI interrupts */
  483. /* 30, 31: reserved */
  484. };
  485. static const bool sse300_irq_is_common[32] = {
  486. [0 ... 5] = true,
  487. /* 6, 7: per-CPU MHU interrupts */
  488. [8 ... 12] = true,
  489. /* 13: reserved */
  490. [14 ... 16] = true,
  491. /* 17-25: reserved */
  492. [26 ... 27] = true,
  493. /* 28, 29: per-CPU CTI interrupts */
  494. /* 30, 31: reserved */
  495. };
  496. static const ARMSSEInfo armsse_variants[] = {
  497. {
  498. .name = TYPE_IOTKIT,
  499. .sse_version = ARMSSE_IOTKIT,
  500. .cpu_type = ARM_CPU_TYPE_NAME("cortex-m33"),
  501. .sram_banks = 1,
  502. .sram_bank_base = 0x20000000,
  503. .num_cpus = 1,
  504. .sys_version = 0x41743,
  505. .iidr = 0,
  506. .cpuwait_rst = 0,
  507. .has_mhus = false,
  508. .has_cachectrl = false,
  509. .has_cpusecctrl = false,
  510. .has_cpuid = false,
  511. .has_cpu_pwrctrl = false,
  512. .has_sse_counter = false,
  513. .has_tcms = false,
  514. .props = iotkit_properties,
  515. .props_count = ARRAY_SIZE(iotkit_properties),
  516. .devinfo = iotkit_devices,
  517. .irq_is_common = sse200_irq_is_common,
  518. },
  519. {
  520. .name = TYPE_SSE200,
  521. .sse_version = ARMSSE_SSE200,
  522. .cpu_type = ARM_CPU_TYPE_NAME("cortex-m33"),
  523. .sram_banks = 4,
  524. .sram_bank_base = 0x20000000,
  525. .num_cpus = 2,
  526. .sys_version = 0x22041743,
  527. .iidr = 0,
  528. .cpuwait_rst = 2,
  529. .has_mhus = true,
  530. .has_cachectrl = true,
  531. .has_cpusecctrl = true,
  532. .has_cpuid = true,
  533. .has_cpu_pwrctrl = false,
  534. .has_sse_counter = false,
  535. .has_tcms = false,
  536. .props = sse200_properties,
  537. .props_count = ARRAY_SIZE(sse200_properties),
  538. .devinfo = sse200_devices,
  539. .irq_is_common = sse200_irq_is_common,
  540. },
  541. {
  542. .name = TYPE_SSE300,
  543. .sse_version = ARMSSE_SSE300,
  544. .cpu_type = ARM_CPU_TYPE_NAME("cortex-m55"),
  545. .sram_banks = 2,
  546. .sram_bank_base = 0x21000000,
  547. .num_cpus = 1,
  548. .sys_version = 0x7e00043b,
  549. .iidr = 0x74a0043b,
  550. .cpuwait_rst = 0,
  551. .has_mhus = false,
  552. .has_cachectrl = false,
  553. .has_cpusecctrl = true,
  554. .has_cpuid = true,
  555. .has_cpu_pwrctrl = true,
  556. .has_sse_counter = true,
  557. .has_tcms = true,
  558. .props = sse300_properties,
  559. .props_count = ARRAY_SIZE(sse300_properties),
  560. .devinfo = sse300_devices,
  561. .irq_is_common = sse300_irq_is_common,
  562. },
  563. };
  564. static uint32_t armsse_sys_config_value(ARMSSE *s, const ARMSSEInfo *info)
  565. {
  566. /* Return the SYS_CONFIG value for this SSE */
  567. uint32_t sys_config;
  568. switch (info->sse_version) {
  569. case ARMSSE_IOTKIT:
  570. sys_config = 0;
  571. sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
  572. sys_config = deposit32(sys_config, 4, 4, s->sram_addr_width - 12);
  573. break;
  574. case ARMSSE_SSE200:
  575. sys_config = 0;
  576. sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
  577. sys_config = deposit32(sys_config, 4, 5, s->sram_addr_width);
  578. sys_config = deposit32(sys_config, 24, 4, 2);
  579. if (info->num_cpus > 1) {
  580. sys_config = deposit32(sys_config, 10, 1, 1);
  581. sys_config = deposit32(sys_config, 20, 4, info->sram_banks - 1);
  582. sys_config = deposit32(sys_config, 28, 4, 2);
  583. }
  584. break;
  585. case ARMSSE_SSE300:
  586. sys_config = 0;
  587. sys_config = deposit32(sys_config, 0, 4, info->sram_banks);
  588. sys_config = deposit32(sys_config, 4, 5, s->sram_addr_width);
  589. sys_config = deposit32(sys_config, 16, 3, 3); /* CPU0 = Cortex-M55 */
  590. break;
  591. default:
  592. g_assert_not_reached();
  593. }
  594. return sys_config;
  595. }
  596. /* Clock frequency in HZ of the 32KHz "slow clock" */
  597. #define S32KCLK (32 * 1000)
  598. /*
  599. * Create an alias region in @container of @size bytes starting at @base
  600. * which mirrors the memory starting at @orig.
  601. */
  602. static void make_alias(ARMSSE *s, MemoryRegion *mr, MemoryRegion *container,
  603. const char *name, hwaddr base, hwaddr size, hwaddr orig)
  604. {
  605. memory_region_init_alias(mr, NULL, name, container, orig, size);
  606. /* The alias is even lower priority than unimplemented_device regions */
  607. memory_region_add_subregion_overlap(container, base, mr, -1500);
  608. }
  609. static void irq_status_forwarder(void *opaque, int n, int level)
  610. {
  611. qemu_irq destirq = opaque;
  612. qemu_set_irq(destirq, level);
  613. }
  614. static void nsccfg_handler(void *opaque, int n, int level)
  615. {
  616. ARMSSE *s = ARM_SSE(opaque);
  617. s->nsccfg = level;
  618. }
  619. static void armsse_forward_ppc(ARMSSE *s, const char *ppcname, int ppcnum)
  620. {
  621. /* Each of the 4 AHB and 4 APB PPCs that might be present in a
  622. * system using the ARMSSE has a collection of control lines which
  623. * are provided by the security controller and which we want to
  624. * expose as control lines on the ARMSSE device itself, so the
  625. * code using the ARMSSE can wire them up to the PPCs.
  626. */
  627. SplitIRQ *splitter = &s->ppc_irq_splitter[ppcnum];
  628. DeviceState *armssedev = DEVICE(s);
  629. DeviceState *dev_secctl = DEVICE(&s->secctl);
  630. DeviceState *dev_splitter = DEVICE(splitter);
  631. char *name;
  632. name = g_strdup_printf("%s_nonsec", ppcname);
  633. qdev_pass_gpios(dev_secctl, armssedev, name);
  634. g_free(name);
  635. name = g_strdup_printf("%s_ap", ppcname);
  636. qdev_pass_gpios(dev_secctl, armssedev, name);
  637. g_free(name);
  638. name = g_strdup_printf("%s_irq_enable", ppcname);
  639. qdev_pass_gpios(dev_secctl, armssedev, name);
  640. g_free(name);
  641. name = g_strdup_printf("%s_irq_clear", ppcname);
  642. qdev_pass_gpios(dev_secctl, armssedev, name);
  643. g_free(name);
  644. /* irq_status is a little more tricky, because we need to
  645. * split it so we can send it both to the security controller
  646. * and to our OR gate for the NVIC interrupt line.
  647. * Connect up the splitter's outputs, and create a GPIO input
  648. * which will pass the line state to the input splitter.
  649. */
  650. name = g_strdup_printf("%s_irq_status", ppcname);
  651. qdev_connect_gpio_out(dev_splitter, 0,
  652. qdev_get_gpio_in_named(dev_secctl,
  653. name, 0));
  654. qdev_connect_gpio_out(dev_splitter, 1,
  655. qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), ppcnum));
  656. s->irq_status_in[ppcnum] = qdev_get_gpio_in(dev_splitter, 0);
  657. qdev_init_gpio_in_named_with_opaque(armssedev, irq_status_forwarder,
  658. s->irq_status_in[ppcnum], name, 1);
  659. g_free(name);
  660. }
  661. static void armsse_forward_sec_resp_cfg(ARMSSE *s)
  662. {
  663. /* Forward the 3rd output from the splitter device as a
  664. * named GPIO output of the armsse object.
  665. */
  666. DeviceState *dev = DEVICE(s);
  667. DeviceState *dev_splitter = DEVICE(&s->sec_resp_splitter);
  668. qdev_init_gpio_out_named(dev, &s->sec_resp_cfg, "sec_resp_cfg", 1);
  669. s->sec_resp_cfg_in = qemu_allocate_irq(irq_status_forwarder,
  670. s->sec_resp_cfg, 1);
  671. qdev_connect_gpio_out(dev_splitter, 2, s->sec_resp_cfg_in);
  672. }
  673. static void armsse_init(Object *obj)
  674. {
  675. ARMSSE *s = ARM_SSE(obj);
  676. ARMSSEClass *asc = ARM_SSE_GET_CLASS(obj);
  677. const ARMSSEInfo *info = asc->info;
  678. const ARMSSEDeviceInfo *devinfo;
  679. int i;
  680. assert(info->sram_banks <= MAX_SRAM_BANKS);
  681. assert(info->num_cpus <= SSE_MAX_CPUS);
  682. s->mainclk = qdev_init_clock_in(DEVICE(s), "MAINCLK", NULL, NULL, 0);
  683. s->s32kclk = qdev_init_clock_in(DEVICE(s), "S32KCLK", NULL, NULL, 0);
  684. memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
  685. for (i = 0; i < info->num_cpus; i++) {
  686. /*
  687. * We put each CPU in its own cluster as they are logically
  688. * distinct and may be configured differently.
  689. */
  690. char *name;
  691. name = g_strdup_printf("cluster%d", i);
  692. object_initialize_child(obj, name, &s->cluster[i], TYPE_CPU_CLUSTER);
  693. qdev_prop_set_uint32(DEVICE(&s->cluster[i]), "cluster-id", i);
  694. g_free(name);
  695. name = g_strdup_printf("armv7m%d", i);
  696. object_initialize_child(OBJECT(&s->cluster[i]), name, &s->armv7m[i],
  697. TYPE_ARMV7M);
  698. qdev_prop_set_string(DEVICE(&s->armv7m[i]), "cpu-type", info->cpu_type);
  699. g_free(name);
  700. name = g_strdup_printf("arm-sse-cpu-container%d", i);
  701. memory_region_init(&s->cpu_container[i], obj, name, UINT64_MAX);
  702. g_free(name);
  703. if (i > 0) {
  704. name = g_strdup_printf("arm-sse-container-alias%d", i);
  705. memory_region_init_alias(&s->container_alias[i - 1], obj,
  706. name, &s->container, 0, UINT64_MAX);
  707. g_free(name);
  708. }
  709. }
  710. for (devinfo = info->devinfo; devinfo->name; devinfo++) {
  711. assert(devinfo->ppc == NO_PPC || devinfo->ppc < ARRAY_SIZE(s->apb_ppc));
  712. if (!strcmp(devinfo->type, TYPE_CMSDK_APB_TIMER)) {
  713. assert(devinfo->index < ARRAY_SIZE(s->timer));
  714. object_initialize_child(obj, devinfo->name,
  715. &s->timer[devinfo->index],
  716. TYPE_CMSDK_APB_TIMER);
  717. } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_DUALTIMER)) {
  718. assert(devinfo->index == 0);
  719. object_initialize_child(obj, devinfo->name, &s->dualtimer,
  720. TYPE_CMSDK_APB_DUALTIMER);
  721. } else if (!strcmp(devinfo->type, TYPE_SSE_TIMER)) {
  722. assert(devinfo->index < ARRAY_SIZE(s->sse_timer));
  723. object_initialize_child(obj, devinfo->name,
  724. &s->sse_timer[devinfo->index],
  725. TYPE_SSE_TIMER);
  726. } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_WATCHDOG)) {
  727. assert(devinfo->index < ARRAY_SIZE(s->cmsdk_watchdog));
  728. object_initialize_child(obj, devinfo->name,
  729. &s->cmsdk_watchdog[devinfo->index],
  730. TYPE_CMSDK_APB_WATCHDOG);
  731. } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSINFO)) {
  732. assert(devinfo->index == 0);
  733. object_initialize_child(obj, devinfo->name, &s->sysinfo,
  734. TYPE_IOTKIT_SYSINFO);
  735. } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSCTL)) {
  736. assert(devinfo->index == 0);
  737. object_initialize_child(obj, devinfo->name, &s->sysctl,
  738. TYPE_IOTKIT_SYSCTL);
  739. } else if (!strcmp(devinfo->type, TYPE_UNIMPLEMENTED_DEVICE)) {
  740. assert(devinfo->index < ARRAY_SIZE(s->unimp));
  741. object_initialize_child(obj, devinfo->name,
  742. &s->unimp[devinfo->index],
  743. TYPE_UNIMPLEMENTED_DEVICE);
  744. } else {
  745. g_assert_not_reached();
  746. }
  747. }
  748. object_initialize_child(obj, "secctl", &s->secctl, TYPE_IOTKIT_SECCTL);
  749. for (i = 0; i < ARRAY_SIZE(s->apb_ppc); i++) {
  750. g_autofree char *name = g_strdup_printf("apb-ppc%d", i);
  751. object_initialize_child(obj, name, &s->apb_ppc[i], TYPE_TZ_PPC);
  752. }
  753. for (i = 0; i < info->sram_banks; i++) {
  754. char *name = g_strdup_printf("mpc%d", i);
  755. object_initialize_child(obj, name, &s->mpc[i], TYPE_TZ_MPC);
  756. g_free(name);
  757. }
  758. object_initialize_child(obj, "mpc-irq-orgate", &s->mpc_irq_orgate,
  759. TYPE_OR_IRQ);
  760. for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
  761. char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
  762. SplitIRQ *splitter = &s->mpc_irq_splitter[i];
  763. object_initialize_child(obj, name, splitter, TYPE_SPLIT_IRQ);
  764. g_free(name);
  765. }
  766. if (info->has_mhus) {
  767. object_initialize_child(obj, "mhu0", &s->mhu[0], TYPE_ARMSSE_MHU);
  768. object_initialize_child(obj, "mhu1", &s->mhu[1], TYPE_ARMSSE_MHU);
  769. }
  770. if (info->has_cachectrl) {
  771. for (i = 0; i < info->num_cpus; i++) {
  772. char *name = g_strdup_printf("cachectrl%d", i);
  773. object_initialize_child(obj, name, &s->cachectrl[i],
  774. TYPE_UNIMPLEMENTED_DEVICE);
  775. g_free(name);
  776. }
  777. }
  778. if (info->has_cpusecctrl) {
  779. for (i = 0; i < info->num_cpus; i++) {
  780. char *name = g_strdup_printf("cpusecctrl%d", i);
  781. object_initialize_child(obj, name, &s->cpusecctrl[i],
  782. TYPE_UNIMPLEMENTED_DEVICE);
  783. g_free(name);
  784. }
  785. }
  786. if (info->has_cpuid) {
  787. for (i = 0; i < info->num_cpus; i++) {
  788. char *name = g_strdup_printf("cpuid%d", i);
  789. object_initialize_child(obj, name, &s->cpuid[i],
  790. TYPE_ARMSSE_CPUID);
  791. g_free(name);
  792. }
  793. }
  794. if (info->has_cpu_pwrctrl) {
  795. for (i = 0; i < info->num_cpus; i++) {
  796. char *name = g_strdup_printf("cpu_pwrctrl%d", i);
  797. object_initialize_child(obj, name, &s->cpu_pwrctrl[i],
  798. TYPE_ARMSSE_CPU_PWRCTRL);
  799. g_free(name);
  800. }
  801. }
  802. if (info->has_sse_counter) {
  803. object_initialize_child(obj, "sse-counter", &s->sse_counter,
  804. TYPE_SSE_COUNTER);
  805. }
  806. object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate, TYPE_OR_IRQ);
  807. object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate,
  808. TYPE_OR_IRQ);
  809. object_initialize_child(obj, "sec-resp-splitter", &s->sec_resp_splitter,
  810. TYPE_SPLIT_IRQ);
  811. for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
  812. char *name = g_strdup_printf("ppc-irq-splitter-%d", i);
  813. SplitIRQ *splitter = &s->ppc_irq_splitter[i];
  814. object_initialize_child(obj, name, splitter, TYPE_SPLIT_IRQ);
  815. g_free(name);
  816. }
  817. if (info->num_cpus > 1) {
  818. for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
  819. if (info->irq_is_common[i]) {
  820. char *name = g_strdup_printf("cpu-irq-splitter%d", i);
  821. SplitIRQ *splitter = &s->cpu_irq_splitter[i];
  822. object_initialize_child(obj, name, splitter, TYPE_SPLIT_IRQ);
  823. g_free(name);
  824. }
  825. }
  826. }
  827. }
  828. static void armsse_exp_irq(void *opaque, int n, int level)
  829. {
  830. qemu_irq *irqarray = opaque;
  831. qemu_set_irq(irqarray[n], level);
  832. }
  833. static void armsse_mpcexp_status(void *opaque, int n, int level)
  834. {
  835. ARMSSE *s = ARM_SSE(opaque);
  836. qemu_set_irq(s->mpcexp_status_in[n], level);
  837. }
  838. static qemu_irq armsse_get_common_irq_in(ARMSSE *s, int irqno)
  839. {
  840. /*
  841. * Return a qemu_irq which can be used to signal IRQ n to
  842. * all CPUs in the SSE.
  843. */
  844. ARMSSEClass *asc = ARM_SSE_GET_CLASS(s);
  845. const ARMSSEInfo *info = asc->info;
  846. assert(info->irq_is_common[irqno]);
  847. if (info->num_cpus == 1) {
  848. /* Only one CPU -- just connect directly to it */
  849. return qdev_get_gpio_in(DEVICE(&s->armv7m[0]), irqno);
  850. } else {
  851. /* Connect to the splitter which feeds all CPUs */
  852. return qdev_get_gpio_in(DEVICE(&s->cpu_irq_splitter[irqno]), 0);
  853. }
  854. }
  855. static void armsse_realize(DeviceState *dev, Error **errp)
  856. {
  857. ERRP_GUARD();
  858. ARMSSE *s = ARM_SSE(dev);
  859. ARMSSEClass *asc = ARM_SSE_GET_CLASS(dev);
  860. const ARMSSEInfo *info = asc->info;
  861. const ARMSSEDeviceInfo *devinfo;
  862. int i;
  863. MemoryRegion *mr;
  864. SysBusDevice *sbd_apb_ppc0;
  865. SysBusDevice *sbd_secctl;
  866. DeviceState *dev_apb_ppc0;
  867. DeviceState *dev_apb_ppc1;
  868. DeviceState *dev_secctl;
  869. DeviceState *dev_splitter;
  870. uint32_t addr_width_max;
  871. if (!s->board_memory) {
  872. error_setg(errp, "memory property was not set");
  873. return;
  874. }
  875. if (!clock_has_source(s->mainclk)) {
  876. error_setg(errp, "MAINCLK clock was not connected");
  877. }
  878. if (!clock_has_source(s->s32kclk)) {
  879. error_setg(errp, "S32KCLK clock was not connected");
  880. }
  881. assert(info->num_cpus <= SSE_MAX_CPUS);
  882. /* max SRAM_ADDR_WIDTH: 24 - log2(SRAM_NUM_BANK) */
  883. assert(is_power_of_2(info->sram_banks));
  884. addr_width_max = 24 - ctz32(info->sram_banks);
  885. if (s->sram_addr_width < 1 || s->sram_addr_width > addr_width_max) {
  886. error_setg(errp, "SRAM_ADDR_WIDTH must be between 1 and %d",
  887. addr_width_max);
  888. return;
  889. }
  890. /* Handling of which devices should be available only to secure
  891. * code is usually done differently for M profile than for A profile.
  892. * Instead of putting some devices only into the secure address space,
  893. * devices exist in both address spaces but with hard-wired security
  894. * permissions that will cause the CPU to fault for non-secure accesses.
  895. *
  896. * The ARMSSE has an IDAU (Implementation Defined Access Unit),
  897. * which specifies hard-wired security permissions for different
  898. * areas of the physical address space. For the ARMSSE IDAU, the
  899. * top 4 bits of the physical address are the IDAU region ID, and
  900. * if bit 28 (ie the lowest bit of the ID) is 0 then this is an NS
  901. * region, otherwise it is an S region.
  902. *
  903. * The various devices and RAMs are generally all mapped twice,
  904. * once into a region that the IDAU defines as secure and once
  905. * into a non-secure region. They sit behind either a Memory
  906. * Protection Controller (for RAM) or a Peripheral Protection
  907. * Controller (for devices), which allow a more fine grained
  908. * configuration of whether non-secure accesses are permitted.
  909. *
  910. * (The other place that guest software can configure security
  911. * permissions is in the architected SAU (Security Attribution
  912. * Unit), which is entirely inside the CPU. The IDAU can upgrade
  913. * the security attributes for a region to more restrictive than
  914. * the SAU specifies, but cannot downgrade them.)
  915. *
  916. * 0x10000000..0x1fffffff alias of 0x00000000..0x0fffffff
  917. * 0x20000000..0x2007ffff 32KB FPGA block RAM
  918. * 0x30000000..0x3fffffff alias of 0x20000000..0x2fffffff
  919. * 0x40000000..0x4000ffff base peripheral region 1
  920. * 0x40010000..0x4001ffff CPU peripherals (none for ARMSSE)
  921. * 0x40020000..0x4002ffff system control element peripherals
  922. * 0x40080000..0x400fffff base peripheral region 2
  923. * 0x50000000..0x5fffffff alias of 0x40000000..0x4fffffff
  924. */
  925. memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -2);
  926. for (i = 0; i < info->num_cpus; i++) {
  927. DeviceState *cpudev = DEVICE(&s->armv7m[i]);
  928. Object *cpuobj = OBJECT(&s->armv7m[i]);
  929. int j;
  930. char *gpioname;
  931. qdev_connect_clock_in(cpudev, "cpuclk", s->mainclk);
  932. /* The SSE subsystems do not wire up a systick refclk */
  933. qdev_prop_set_uint32(cpudev, "num-irq", s->exp_numirq + NUM_SSE_IRQS);
  934. /*
  935. * In real hardware the initial Secure VTOR is set from the INITSVTOR*
  936. * registers in the IoT Kit System Control Register block. In QEMU
  937. * we set the initial value here, and also the reset value of the
  938. * sysctl register, from this object's QOM init-svtor property.
  939. * If the guest changes the INITSVTOR* registers at runtime then the
  940. * code in iotkit-sysctl.c will update the CPU init-svtor property
  941. * (which will then take effect on the next CPU warm-reset).
  942. *
  943. * Note that typically a board using the SSE-200 will have a system
  944. * control processor whose boot firmware initializes the INITSVTOR*
  945. * registers before powering up the CPUs. QEMU doesn't emulate
  946. * the control processor, so instead we behave in the way that the
  947. * firmware does: the initial value should be set by the board code
  948. * (using the init-svtor property on the ARMSSE object) to match
  949. * whatever its firmware does.
  950. */
  951. qdev_prop_set_uint32(cpudev, "init-svtor", s->init_svtor);
  952. /*
  953. * CPUs start powered down if the corresponding bit in the CPUWAIT
  954. * register is 1. In real hardware the CPUWAIT register reset value is
  955. * a configurable property of the SSE-200 (via the CPUWAIT0_RST and
  956. * CPUWAIT1_RST parameters), but since all the boards we care about
  957. * start CPU0 and leave CPU1 powered off, we hard-code that in
  958. * info->cpuwait_rst for now. We can add QOM properties for this
  959. * later if necessary.
  960. */
  961. if (extract32(info->cpuwait_rst, i, 1)) {
  962. object_property_set_bool(cpuobj, "start-powered-off", true,
  963. &error_abort);
  964. }
  965. if (!s->cpu_fpu[i]) {
  966. if (!object_property_set_bool(cpuobj, "vfp", false, errp)) {
  967. return;
  968. }
  969. }
  970. if (!s->cpu_dsp[i]) {
  971. if (!object_property_set_bool(cpuobj, "dsp", false, errp)) {
  972. return;
  973. }
  974. }
  975. if (!object_property_set_uint(cpuobj, "mpu-ns-regions",
  976. s->cpu_mpu_ns[i], errp)) {
  977. return;
  978. }
  979. if (!object_property_set_uint(cpuobj, "mpu-s-regions",
  980. s->cpu_mpu_s[i], errp)) {
  981. return;
  982. }
  983. if (i > 0) {
  984. memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
  985. &s->container_alias[i - 1], -1);
  986. } else {
  987. memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
  988. &s->container, -1);
  989. }
  990. object_property_set_link(cpuobj, "memory",
  991. OBJECT(&s->cpu_container[i]), &error_abort);
  992. object_property_set_link(cpuobj, "idau", OBJECT(s), &error_abort);
  993. if (!sysbus_realize(SYS_BUS_DEVICE(cpuobj), errp)) {
  994. return;
  995. }
  996. /*
  997. * The cluster must be realized after the armv7m container, as
  998. * the container's CPU object is only created on realize, and the
  999. * CPU must exist and have been parented into the cluster before
  1000. * the cluster is realized.
  1001. */
  1002. if (!qdev_realize(DEVICE(&s->cluster[i]), NULL, errp)) {
  1003. return;
  1004. }
  1005. /* Connect EXP_IRQ/EXP_CPUn_IRQ GPIOs to the NVIC's lines 32 and up */
  1006. s->exp_irqs[i] = g_new(qemu_irq, s->exp_numirq);
  1007. for (j = 0; j < s->exp_numirq; j++) {
  1008. s->exp_irqs[i][j] = qdev_get_gpio_in(cpudev, j + NUM_SSE_IRQS);
  1009. }
  1010. if (i == 0) {
  1011. gpioname = g_strdup("EXP_IRQ");
  1012. } else {
  1013. gpioname = g_strdup_printf("EXP_CPU%d_IRQ", i);
  1014. }
  1015. qdev_init_gpio_in_named_with_opaque(dev, armsse_exp_irq,
  1016. s->exp_irqs[i],
  1017. gpioname, s->exp_numirq);
  1018. g_free(gpioname);
  1019. }
  1020. /* Wire up the splitters that connect common IRQs to all CPUs */
  1021. if (info->num_cpus > 1) {
  1022. for (i = 0; i < ARRAY_SIZE(s->cpu_irq_splitter); i++) {
  1023. if (info->irq_is_common[i]) {
  1024. Object *splitter = OBJECT(&s->cpu_irq_splitter[i]);
  1025. DeviceState *devs = DEVICE(splitter);
  1026. int cpunum;
  1027. if (!object_property_set_int(splitter, "num-lines",
  1028. info->num_cpus, errp)) {
  1029. return;
  1030. }
  1031. if (!qdev_realize(DEVICE(splitter), NULL, errp)) {
  1032. return;
  1033. }
  1034. for (cpunum = 0; cpunum < info->num_cpus; cpunum++) {
  1035. DeviceState *cpudev = DEVICE(&s->armv7m[cpunum]);
  1036. qdev_connect_gpio_out(devs, cpunum,
  1037. qdev_get_gpio_in(cpudev, i));
  1038. }
  1039. }
  1040. }
  1041. }
  1042. /* Set up the big aliases first */
  1043. make_alias(s, &s->alias1, &s->container, "alias 1",
  1044. 0x10000000, 0x10000000, 0x00000000);
  1045. make_alias(s, &s->alias2, &s->container,
  1046. "alias 2", 0x30000000, 0x10000000, 0x20000000);
  1047. /* The 0x50000000..0x5fffffff region is not a pure alias: it has
  1048. * a few extra devices that only appear there (generally the
  1049. * control interfaces for the protection controllers).
  1050. * We implement this by mapping those devices over the top of this
  1051. * alias MR at a higher priority. Some of the devices in this range
  1052. * are per-CPU, so we must put this alias in the per-cpu containers.
  1053. */
  1054. for (i = 0; i < info->num_cpus; i++) {
  1055. make_alias(s, &s->alias3[i], &s->cpu_container[i],
  1056. "alias 3", 0x50000000, 0x10000000, 0x40000000);
  1057. }
  1058. /* Security controller */
  1059. object_property_set_int(OBJECT(&s->secctl), "sse-version",
  1060. info->sse_version, &error_abort);
  1061. if (!sysbus_realize(SYS_BUS_DEVICE(&s->secctl), errp)) {
  1062. return;
  1063. }
  1064. sbd_secctl = SYS_BUS_DEVICE(&s->secctl);
  1065. dev_secctl = DEVICE(&s->secctl);
  1066. sysbus_mmio_map(sbd_secctl, 0, 0x50080000);
  1067. sysbus_mmio_map(sbd_secctl, 1, 0x40080000);
  1068. s->nsc_cfg_in = qemu_allocate_irq(nsccfg_handler, s, 1);
  1069. qdev_connect_gpio_out_named(dev_secctl, "nsc_cfg", 0, s->nsc_cfg_in);
  1070. /* The sec_resp_cfg output from the security controller must be split into
  1071. * multiple lines, one for each of the PPCs within the ARMSSE and one
  1072. * that will be an output from the ARMSSE to the system.
  1073. */
  1074. if (!object_property_set_int(OBJECT(&s->sec_resp_splitter),
  1075. "num-lines", 3, errp)) {
  1076. return;
  1077. }
  1078. if (!qdev_realize(DEVICE(&s->sec_resp_splitter), NULL, errp)) {
  1079. return;
  1080. }
  1081. dev_splitter = DEVICE(&s->sec_resp_splitter);
  1082. qdev_connect_gpio_out_named(dev_secctl, "sec_resp_cfg", 0,
  1083. qdev_get_gpio_in(dev_splitter, 0));
  1084. /* Each SRAM bank lives behind its own Memory Protection Controller */
  1085. for (i = 0; i < info->sram_banks; i++) {
  1086. char *ramname = g_strdup_printf("armsse.sram%d", i);
  1087. SysBusDevice *sbd_mpc;
  1088. uint32_t sram_bank_size = 1 << s->sram_addr_width;
  1089. memory_region_init_ram(&s->sram[i], NULL, ramname,
  1090. sram_bank_size, errp);
  1091. g_free(ramname);
  1092. if (*errp) {
  1093. return;
  1094. }
  1095. object_property_set_link(OBJECT(&s->mpc[i]), "downstream",
  1096. OBJECT(&s->sram[i]), &error_abort);
  1097. if (!sysbus_realize(SYS_BUS_DEVICE(&s->mpc[i]), errp)) {
  1098. return;
  1099. }
  1100. /* Map the upstream end of the MPC into the right place... */
  1101. sbd_mpc = SYS_BUS_DEVICE(&s->mpc[i]);
  1102. memory_region_add_subregion(&s->container,
  1103. info->sram_bank_base + i * sram_bank_size,
  1104. sysbus_mmio_get_region(sbd_mpc, 1));
  1105. /* ...and its register interface */
  1106. memory_region_add_subregion(&s->container, 0x50083000 + i * 0x1000,
  1107. sysbus_mmio_get_region(sbd_mpc, 0));
  1108. }
  1109. /* We must OR together lines from the MPC splitters to go to the NVIC */
  1110. if (!object_property_set_int(OBJECT(&s->mpc_irq_orgate), "num-lines",
  1111. IOTS_NUM_EXP_MPC + info->sram_banks,
  1112. errp)) {
  1113. return;
  1114. }
  1115. if (!qdev_realize(DEVICE(&s->mpc_irq_orgate), NULL, errp)) {
  1116. return;
  1117. }
  1118. qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
  1119. armsse_get_common_irq_in(s, 9));
  1120. /* This OR gate wires together outputs from the secure watchdogs to NMI */
  1121. if (!object_property_set_int(OBJECT(&s->nmi_orgate), "num-lines", 2,
  1122. errp)) {
  1123. return;
  1124. }
  1125. if (!qdev_realize(DEVICE(&s->nmi_orgate), NULL, errp)) {
  1126. return;
  1127. }
  1128. qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0,
  1129. qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0));
  1130. /* The SSE-300 has a System Counter / System Timestamp Generator */
  1131. if (info->has_sse_counter) {
  1132. SysBusDevice *sbd = SYS_BUS_DEVICE(&s->sse_counter);
  1133. qdev_connect_clock_in(DEVICE(sbd), "CLK", s->mainclk);
  1134. if (!sysbus_realize(sbd, errp)) {
  1135. return;
  1136. }
  1137. /*
  1138. * The control frame is only in the Secure region;
  1139. * the status frame is in the NS region (and visible in the
  1140. * S region via the alias mapping).
  1141. */
  1142. memory_region_add_subregion(&s->container, 0x58100000,
  1143. sysbus_mmio_get_region(sbd, 0));
  1144. memory_region_add_subregion(&s->container, 0x48101000,
  1145. sysbus_mmio_get_region(sbd, 1));
  1146. }
  1147. if (info->has_tcms) {
  1148. /* The SSE-300 has an ITCM at 0x0000_0000 and a DTCM at 0x2000_0000 */
  1149. memory_region_init_ram(&s->itcm, NULL, "sse300-itcm", 512 * KiB, errp);
  1150. if (*errp) {
  1151. return;
  1152. }
  1153. memory_region_init_ram(&s->dtcm, NULL, "sse300-dtcm", 512 * KiB, errp);
  1154. if (*errp) {
  1155. return;
  1156. }
  1157. memory_region_add_subregion(&s->container, 0x00000000, &s->itcm);
  1158. memory_region_add_subregion(&s->container, 0x20000000, &s->dtcm);
  1159. }
  1160. /* Devices behind APB PPC0:
  1161. * 0x40000000: timer0
  1162. * 0x40001000: timer1
  1163. * 0x40002000: dual timer
  1164. * 0x40003000: MHU0 (SSE-200 only)
  1165. * 0x40004000: MHU1 (SSE-200 only)
  1166. * We must configure and realize each downstream device and connect
  1167. * it to the appropriate PPC port; then we can realize the PPC and
  1168. * map its upstream ends to the right place in the container.
  1169. */
  1170. for (devinfo = info->devinfo; devinfo->name; devinfo++) {
  1171. SysBusDevice *sbd;
  1172. qemu_irq irq;
  1173. if (!strcmp(devinfo->type, TYPE_CMSDK_APB_TIMER)) {
  1174. sbd = SYS_BUS_DEVICE(&s->timer[devinfo->index]);
  1175. qdev_connect_clock_in(DEVICE(sbd), "pclk",
  1176. devinfo->slowclk ? s->s32kclk : s->mainclk);
  1177. if (!sysbus_realize(sbd, errp)) {
  1178. return;
  1179. }
  1180. mr = sysbus_mmio_get_region(sbd, 0);
  1181. } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_DUALTIMER)) {
  1182. sbd = SYS_BUS_DEVICE(&s->dualtimer);
  1183. qdev_connect_clock_in(DEVICE(sbd), "TIMCLK", s->mainclk);
  1184. if (!sysbus_realize(sbd, errp)) {
  1185. return;
  1186. }
  1187. mr = sysbus_mmio_get_region(sbd, 0);
  1188. } else if (!strcmp(devinfo->type, TYPE_SSE_TIMER)) {
  1189. sbd = SYS_BUS_DEVICE(&s->sse_timer[devinfo->index]);
  1190. assert(info->has_sse_counter);
  1191. object_property_set_link(OBJECT(sbd), "counter",
  1192. OBJECT(&s->sse_counter), &error_abort);
  1193. if (!sysbus_realize(sbd, errp)) {
  1194. return;
  1195. }
  1196. mr = sysbus_mmio_get_region(sbd, 0);
  1197. } else if (!strcmp(devinfo->type, TYPE_CMSDK_APB_WATCHDOG)) {
  1198. sbd = SYS_BUS_DEVICE(&s->cmsdk_watchdog[devinfo->index]);
  1199. qdev_connect_clock_in(DEVICE(sbd), "WDOGCLK",
  1200. devinfo->slowclk ? s->s32kclk : s->mainclk);
  1201. if (!sysbus_realize(sbd, errp)) {
  1202. return;
  1203. }
  1204. mr = sysbus_mmio_get_region(sbd, 0);
  1205. } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSINFO)) {
  1206. sbd = SYS_BUS_DEVICE(&s->sysinfo);
  1207. object_property_set_int(OBJECT(&s->sysinfo), "SYS_VERSION",
  1208. info->sys_version, &error_abort);
  1209. object_property_set_int(OBJECT(&s->sysinfo), "SYS_CONFIG",
  1210. armsse_sys_config_value(s, info),
  1211. &error_abort);
  1212. object_property_set_int(OBJECT(&s->sysinfo), "sse-version",
  1213. info->sse_version, &error_abort);
  1214. object_property_set_int(OBJECT(&s->sysinfo), "IIDR",
  1215. info->iidr, &error_abort);
  1216. if (!sysbus_realize(sbd, errp)) {
  1217. return;
  1218. }
  1219. mr = sysbus_mmio_get_region(sbd, 0);
  1220. } else if (!strcmp(devinfo->type, TYPE_IOTKIT_SYSCTL)) {
  1221. /* System control registers */
  1222. sbd = SYS_BUS_DEVICE(&s->sysctl);
  1223. object_property_set_int(OBJECT(&s->sysctl), "sse-version",
  1224. info->sse_version, &error_abort);
  1225. object_property_set_int(OBJECT(&s->sysctl), "CPUWAIT_RST",
  1226. info->cpuwait_rst, &error_abort);
  1227. object_property_set_int(OBJECT(&s->sysctl), "INITSVTOR0_RST",
  1228. s->init_svtor, &error_abort);
  1229. object_property_set_int(OBJECT(&s->sysctl), "INITSVTOR1_RST",
  1230. s->init_svtor, &error_abort);
  1231. if (!sysbus_realize(sbd, errp)) {
  1232. return;
  1233. }
  1234. mr = sysbus_mmio_get_region(sbd, 0);
  1235. } else if (!strcmp(devinfo->type, TYPE_UNIMPLEMENTED_DEVICE)) {
  1236. sbd = SYS_BUS_DEVICE(&s->unimp[devinfo->index]);
  1237. qdev_prop_set_string(DEVICE(sbd), "name", devinfo->name);
  1238. qdev_prop_set_uint64(DEVICE(sbd), "size", devinfo->size);
  1239. if (!sysbus_realize(sbd, errp)) {
  1240. return;
  1241. }
  1242. mr = sysbus_mmio_get_region(sbd, 0);
  1243. } else {
  1244. g_assert_not_reached();
  1245. }
  1246. switch (devinfo->irq) {
  1247. case NO_IRQ:
  1248. irq = NULL;
  1249. break;
  1250. case 0 ... NUM_SSE_IRQS - 1:
  1251. irq = armsse_get_common_irq_in(s, devinfo->irq);
  1252. break;
  1253. case NMI_0:
  1254. case NMI_1:
  1255. irq = qdev_get_gpio_in(DEVICE(&s->nmi_orgate),
  1256. devinfo->irq - NMI_0);
  1257. break;
  1258. default:
  1259. g_assert_not_reached();
  1260. }
  1261. if (irq) {
  1262. sysbus_connect_irq(sbd, 0, irq);
  1263. }
  1264. /*
  1265. * Devices connected to a PPC are connected to the port here;
  1266. * we will map the upstream end of that port to the right address
  1267. * in the container later after the PPC has been realized.
  1268. * Devices not connected to a PPC can be mapped immediately.
  1269. */
  1270. if (devinfo->ppc != NO_PPC) {
  1271. TZPPC *ppc = &s->apb_ppc[devinfo->ppc];
  1272. g_autofree char *portname = g_strdup_printf("port[%d]",
  1273. devinfo->ppc_port);
  1274. object_property_set_link(OBJECT(ppc), portname, OBJECT(mr),
  1275. &error_abort);
  1276. } else {
  1277. memory_region_add_subregion(&s->container, devinfo->addr, mr);
  1278. }
  1279. }
  1280. if (info->has_mhus) {
  1281. /*
  1282. * An SSE-200 with only one CPU should have only one MHU created,
  1283. * with the region where the second MHU usually is being RAZ/WI.
  1284. * We don't implement that SSE-200 config; if we want to support
  1285. * it then this code needs to be enhanced to handle creating the
  1286. * RAZ/WI region instead of the second MHU.
  1287. */
  1288. assert(info->num_cpus == ARRAY_SIZE(s->mhu));
  1289. for (i = 0; i < ARRAY_SIZE(s->mhu); i++) {
  1290. char *port;
  1291. int cpunum;
  1292. SysBusDevice *mhu_sbd = SYS_BUS_DEVICE(&s->mhu[i]);
  1293. if (!sysbus_realize(SYS_BUS_DEVICE(&s->mhu[i]), errp)) {
  1294. return;
  1295. }
  1296. port = g_strdup_printf("port[%d]", i + 3);
  1297. mr = sysbus_mmio_get_region(mhu_sbd, 0);
  1298. object_property_set_link(OBJECT(&s->apb_ppc[0]), port, OBJECT(mr),
  1299. &error_abort);
  1300. g_free(port);
  1301. /*
  1302. * Each MHU has an irq line for each CPU:
  1303. * MHU 0 irq line 0 -> CPU 0 IRQ 6
  1304. * MHU 0 irq line 1 -> CPU 1 IRQ 6
  1305. * MHU 1 irq line 0 -> CPU 0 IRQ 7
  1306. * MHU 1 irq line 1 -> CPU 1 IRQ 7
  1307. */
  1308. for (cpunum = 0; cpunum < info->num_cpus; cpunum++) {
  1309. DeviceState *cpudev = DEVICE(&s->armv7m[cpunum]);
  1310. sysbus_connect_irq(mhu_sbd, cpunum,
  1311. qdev_get_gpio_in(cpudev, 6 + i));
  1312. }
  1313. }
  1314. }
  1315. if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc[0]), errp)) {
  1316. return;
  1317. }
  1318. sbd_apb_ppc0 = SYS_BUS_DEVICE(&s->apb_ppc[0]);
  1319. dev_apb_ppc0 = DEVICE(&s->apb_ppc[0]);
  1320. if (info->has_mhus) {
  1321. mr = sysbus_mmio_get_region(sbd_apb_ppc0, 3);
  1322. memory_region_add_subregion(&s->container, 0x40003000, mr);
  1323. mr = sysbus_mmio_get_region(sbd_apb_ppc0, 4);
  1324. memory_region_add_subregion(&s->container, 0x40004000, mr);
  1325. }
  1326. for (i = 0; i < IOTS_APB_PPC0_NUM_PORTS; i++) {
  1327. qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_nonsec", i,
  1328. qdev_get_gpio_in_named(dev_apb_ppc0,
  1329. "cfg_nonsec", i));
  1330. qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_ap", i,
  1331. qdev_get_gpio_in_named(dev_apb_ppc0,
  1332. "cfg_ap", i));
  1333. }
  1334. qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_enable", 0,
  1335. qdev_get_gpio_in_named(dev_apb_ppc0,
  1336. "irq_enable", 0));
  1337. qdev_connect_gpio_out_named(dev_secctl, "apb_ppc0_irq_clear", 0,
  1338. qdev_get_gpio_in_named(dev_apb_ppc0,
  1339. "irq_clear", 0));
  1340. qdev_connect_gpio_out(dev_splitter, 0,
  1341. qdev_get_gpio_in_named(dev_apb_ppc0,
  1342. "cfg_sec_resp", 0));
  1343. /* All the PPC irq lines (from the 2 internal PPCs and the 8 external
  1344. * ones) are sent individually to the security controller, and also
  1345. * ORed together to give a single combined PPC interrupt to the NVIC.
  1346. */
  1347. if (!object_property_set_int(OBJECT(&s->ppc_irq_orgate),
  1348. "num-lines", NUM_PPCS, errp)) {
  1349. return;
  1350. }
  1351. if (!qdev_realize(DEVICE(&s->ppc_irq_orgate), NULL, errp)) {
  1352. return;
  1353. }
  1354. qdev_connect_gpio_out(DEVICE(&s->ppc_irq_orgate), 0,
  1355. armsse_get_common_irq_in(s, 10));
  1356. /*
  1357. * 0x40010000 .. 0x4001ffff (and the 0x5001000... secure-only alias):
  1358. * private per-CPU region (all these devices are SSE-200 only):
  1359. * 0x50010000: L1 icache control registers
  1360. * 0x50011000: CPUSECCTRL (CPU local security control registers)
  1361. * 0x4001f000 and 0x5001f000: CPU_IDENTITY register block
  1362. * The SSE-300 has an extra:
  1363. * 0x40012000 and 0x50012000: CPU_PWRCTRL register block
  1364. */
  1365. if (info->has_cachectrl) {
  1366. for (i = 0; i < info->num_cpus; i++) {
  1367. char *name = g_strdup_printf("cachectrl%d", i);
  1368. qdev_prop_set_string(DEVICE(&s->cachectrl[i]), "name", name);
  1369. g_free(name);
  1370. qdev_prop_set_uint64(DEVICE(&s->cachectrl[i]), "size", 0x1000);
  1371. if (!sysbus_realize(SYS_BUS_DEVICE(&s->cachectrl[i]), errp)) {
  1372. return;
  1373. }
  1374. mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cachectrl[i]), 0);
  1375. memory_region_add_subregion(&s->cpu_container[i], 0x50010000, mr);
  1376. }
  1377. }
  1378. if (info->has_cpusecctrl) {
  1379. for (i = 0; i < info->num_cpus; i++) {
  1380. char *name = g_strdup_printf("CPUSECCTRL%d", i);
  1381. qdev_prop_set_string(DEVICE(&s->cpusecctrl[i]), "name", name);
  1382. g_free(name);
  1383. qdev_prop_set_uint64(DEVICE(&s->cpusecctrl[i]), "size", 0x1000);
  1384. if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpusecctrl[i]), errp)) {
  1385. return;
  1386. }
  1387. mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpusecctrl[i]), 0);
  1388. memory_region_add_subregion(&s->cpu_container[i], 0x50011000, mr);
  1389. }
  1390. }
  1391. if (info->has_cpuid) {
  1392. for (i = 0; i < info->num_cpus; i++) {
  1393. qdev_prop_set_uint32(DEVICE(&s->cpuid[i]), "CPUID", i);
  1394. if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpuid[i]), errp)) {
  1395. return;
  1396. }
  1397. mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpuid[i]), 0);
  1398. memory_region_add_subregion(&s->cpu_container[i], 0x4001F000, mr);
  1399. }
  1400. }
  1401. if (info->has_cpu_pwrctrl) {
  1402. for (i = 0; i < info->num_cpus; i++) {
  1403. if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpu_pwrctrl[i]), errp)) {
  1404. return;
  1405. }
  1406. mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpu_pwrctrl[i]), 0);
  1407. memory_region_add_subregion(&s->cpu_container[i], 0x40012000, mr);
  1408. }
  1409. }
  1410. if (!sysbus_realize(SYS_BUS_DEVICE(&s->apb_ppc[1]), errp)) {
  1411. return;
  1412. }
  1413. dev_apb_ppc1 = DEVICE(&s->apb_ppc[1]);
  1414. qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_nonsec", 0,
  1415. qdev_get_gpio_in_named(dev_apb_ppc1,
  1416. "cfg_nonsec", 0));
  1417. qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_ap", 0,
  1418. qdev_get_gpio_in_named(dev_apb_ppc1,
  1419. "cfg_ap", 0));
  1420. qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_enable", 0,
  1421. qdev_get_gpio_in_named(dev_apb_ppc1,
  1422. "irq_enable", 0));
  1423. qdev_connect_gpio_out_named(dev_secctl, "apb_ppc1_irq_clear", 0,
  1424. qdev_get_gpio_in_named(dev_apb_ppc1,
  1425. "irq_clear", 0));
  1426. qdev_connect_gpio_out(dev_splitter, 1,
  1427. qdev_get_gpio_in_named(dev_apb_ppc1,
  1428. "cfg_sec_resp", 0));
  1429. /*
  1430. * Now both PPCs are realized we can map the upstream ends of
  1431. * ports which correspond to entries in the devinfo array.
  1432. * The ports which are connected to non-devinfo devices have
  1433. * already been mapped.
  1434. */
  1435. for (devinfo = info->devinfo; devinfo->name; devinfo++) {
  1436. SysBusDevice *ppc_sbd;
  1437. if (devinfo->ppc == NO_PPC) {
  1438. continue;
  1439. }
  1440. ppc_sbd = SYS_BUS_DEVICE(&s->apb_ppc[devinfo->ppc]);
  1441. mr = sysbus_mmio_get_region(ppc_sbd, devinfo->ppc_port);
  1442. memory_region_add_subregion(&s->container, devinfo->addr, mr);
  1443. }
  1444. for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) {
  1445. Object *splitter = OBJECT(&s->ppc_irq_splitter[i]);
  1446. if (!object_property_set_int(splitter, "num-lines", 2, errp)) {
  1447. return;
  1448. }
  1449. if (!qdev_realize(DEVICE(splitter), NULL, errp)) {
  1450. return;
  1451. }
  1452. }
  1453. for (i = 0; i < IOTS_NUM_AHB_EXP_PPC; i++) {
  1454. char *ppcname = g_strdup_printf("ahb_ppcexp%d", i);
  1455. armsse_forward_ppc(s, ppcname, i);
  1456. g_free(ppcname);
  1457. }
  1458. for (i = 0; i < IOTS_NUM_APB_EXP_PPC; i++) {
  1459. char *ppcname = g_strdup_printf("apb_ppcexp%d", i);
  1460. armsse_forward_ppc(s, ppcname, i + IOTS_NUM_AHB_EXP_PPC);
  1461. g_free(ppcname);
  1462. }
  1463. for (i = NUM_EXTERNAL_PPCS; i < NUM_PPCS; i++) {
  1464. /* Wire up IRQ splitter for internal PPCs */
  1465. DeviceState *devs = DEVICE(&s->ppc_irq_splitter[i]);
  1466. char *gpioname = g_strdup_printf("apb_ppc%d_irq_status",
  1467. i - NUM_EXTERNAL_PPCS);
  1468. TZPPC *ppc = &s->apb_ppc[i - NUM_EXTERNAL_PPCS];
  1469. qdev_connect_gpio_out(devs, 0,
  1470. qdev_get_gpio_in_named(dev_secctl, gpioname, 0));
  1471. qdev_connect_gpio_out(devs, 1,
  1472. qdev_get_gpio_in(DEVICE(&s->ppc_irq_orgate), i));
  1473. qdev_connect_gpio_out_named(DEVICE(ppc), "irq", 0,
  1474. qdev_get_gpio_in(devs, 0));
  1475. g_free(gpioname);
  1476. }
  1477. /* Wire up the splitters for the MPC IRQs */
  1478. for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
  1479. SplitIRQ *splitter = &s->mpc_irq_splitter[i];
  1480. DeviceState *devs = DEVICE(splitter);
  1481. if (!object_property_set_int(OBJECT(splitter), "num-lines", 2,
  1482. errp)) {
  1483. return;
  1484. }
  1485. if (!qdev_realize(DEVICE(splitter), NULL, errp)) {
  1486. return;
  1487. }
  1488. if (i < IOTS_NUM_EXP_MPC) {
  1489. /* Splitter input is from GPIO input line */
  1490. s->mpcexp_status_in[i] = qdev_get_gpio_in(devs, 0);
  1491. qdev_connect_gpio_out(devs, 0,
  1492. qdev_get_gpio_in_named(dev_secctl,
  1493. "mpcexp_status", i));
  1494. } else {
  1495. /* Splitter input is from our own MPC */
  1496. qdev_connect_gpio_out_named(DEVICE(&s->mpc[i - IOTS_NUM_EXP_MPC]),
  1497. "irq", 0,
  1498. qdev_get_gpio_in(devs, 0));
  1499. qdev_connect_gpio_out(devs, 0,
  1500. qdev_get_gpio_in_named(dev_secctl,
  1501. "mpc_status",
  1502. i - IOTS_NUM_EXP_MPC));
  1503. }
  1504. qdev_connect_gpio_out(devs, 1,
  1505. qdev_get_gpio_in(DEVICE(&s->mpc_irq_orgate), i));
  1506. }
  1507. /* Create GPIO inputs which will pass the line state for our
  1508. * mpcexp_irq inputs to the correct splitter devices.
  1509. */
  1510. qdev_init_gpio_in_named(dev, armsse_mpcexp_status, "mpcexp_status",
  1511. IOTS_NUM_EXP_MPC);
  1512. armsse_forward_sec_resp_cfg(s);
  1513. /* Forward the MSC related signals */
  1514. qdev_pass_gpios(dev_secctl, dev, "mscexp_status");
  1515. qdev_pass_gpios(dev_secctl, dev, "mscexp_clear");
  1516. qdev_pass_gpios(dev_secctl, dev, "mscexp_ns");
  1517. qdev_connect_gpio_out_named(dev_secctl, "msc_irq", 0,
  1518. armsse_get_common_irq_in(s, 11));
  1519. /*
  1520. * Expose our container region to the board model; this corresponds
  1521. * to the AHB Slave Expansion ports which allow bus master devices
  1522. * (eg DMA controllers) in the board model to make transactions into
  1523. * devices in the ARMSSE.
  1524. */
  1525. sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container);
  1526. }
  1527. static void armsse_idau_check(IDAUInterface *ii, uint32_t address,
  1528. int *iregion, bool *exempt, bool *ns, bool *nsc)
  1529. {
  1530. /*
  1531. * For ARMSSE systems the IDAU responses are simple logical functions
  1532. * of the address bits. The NSC attribute is guest-adjustable via the
  1533. * NSCCFG register in the security controller.
  1534. */
  1535. ARMSSE *s = ARM_SSE(ii);
  1536. int region = extract32(address, 28, 4);
  1537. *ns = !(region & 1);
  1538. *nsc = (region == 1 && (s->nsccfg & 1)) || (region == 3 && (s->nsccfg & 2));
  1539. /* 0xe0000000..0xe00fffff and 0xf0000000..0xf00fffff are exempt */
  1540. *exempt = (address & 0xeff00000) == 0xe0000000;
  1541. *iregion = region;
  1542. }
  1543. static const VMStateDescription armsse_vmstate = {
  1544. .name = "iotkit",
  1545. .version_id = 2,
  1546. .minimum_version_id = 2,
  1547. .fields = (const VMStateField[]) {
  1548. VMSTATE_CLOCK(mainclk, ARMSSE),
  1549. VMSTATE_CLOCK(s32kclk, ARMSSE),
  1550. VMSTATE_UINT32(nsccfg, ARMSSE),
  1551. VMSTATE_END_OF_LIST()
  1552. }
  1553. };
  1554. static void armsse_reset(DeviceState *dev)
  1555. {
  1556. ARMSSE *s = ARM_SSE(dev);
  1557. s->nsccfg = 0;
  1558. }
  1559. static void armsse_class_init(ObjectClass *klass, void *data)
  1560. {
  1561. DeviceClass *dc = DEVICE_CLASS(klass);
  1562. IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass);
  1563. ARMSSEClass *asc = ARM_SSE_CLASS(klass);
  1564. const ARMSSEInfo *info = data;
  1565. dc->realize = armsse_realize;
  1566. dc->vmsd = &armsse_vmstate;
  1567. device_class_set_props_n(dc, info->props, info->props_count);
  1568. device_class_set_legacy_reset(dc, armsse_reset);
  1569. iic->check = armsse_idau_check;
  1570. asc->info = info;
  1571. }
  1572. static const TypeInfo armsse_info = {
  1573. .name = TYPE_ARM_SSE,
  1574. .parent = TYPE_SYS_BUS_DEVICE,
  1575. .instance_size = sizeof(ARMSSE),
  1576. .class_size = sizeof(ARMSSEClass),
  1577. .instance_init = armsse_init,
  1578. .abstract = true,
  1579. .interfaces = (InterfaceInfo[]) {
  1580. { TYPE_IDAU_INTERFACE },
  1581. { }
  1582. }
  1583. };
  1584. static void armsse_register_types(void)
  1585. {
  1586. int i;
  1587. type_register_static(&armsse_info);
  1588. for (i = 0; i < ARRAY_SIZE(armsse_variants); i++) {
  1589. TypeInfo ti = {
  1590. .name = armsse_variants[i].name,
  1591. .parent = TYPE_ARM_SSE,
  1592. .class_init = armsse_class_init,
  1593. .class_data = (void *)&armsse_variants[i],
  1594. };
  1595. type_register_static(&ti);
  1596. }
  1597. }
  1598. type_init(armsse_register_types);