2
0

astro.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954
  1. /*
  2. * HP-PARISC Astro/Pluto/Ike/REO system bus adapter (SBA)
  3. * with Elroy PCI bus (LBA) adapter emulation
  4. * Found in C3000 and similar machines
  5. *
  6. * (C) 2023 by Helge Deller <deller@gmx.de>
  7. *
  8. * This work is licensed under the GNU GPL license version 2 or later.
  9. *
  10. * Chip documentation is available at:
  11. * https://parisc.wiki.kernel.org/index.php/Technical_Documentation
  12. *
  13. * TODO:
  14. * - All user-added devices are currently attached to the first
  15. * Elroy (PCI bus) only for now. To fix this additional work in
  16. * SeaBIOS and this driver is needed. See "user_creatable" flag below.
  17. * - GMMIO (Greater than 4 GB MMIO) register
  18. */
  19. #define TYPE_ASTRO_IOMMU_MEMORY_REGION "astro-iommu-memory-region"
  20. #define F_EXTEND(addr) ((addr) | MAKE_64BIT_MASK(32, 32))
  21. #include "qemu/osdep.h"
  22. #include "qemu/module.h"
  23. #include "qemu/units.h"
  24. #include "qapi/error.h"
  25. #include "hw/irq.h"
  26. #include "hw/pci/pci_device.h"
  27. #include "hw/pci/pci_bus.h"
  28. #include "hw/qdev-properties.h"
  29. #include "hw/pci-host/astro.h"
  30. #include "hw/hppa/hppa_hardware.h"
  31. #include "migration/vmstate.h"
  32. #include "target/hppa/cpu.h"
  33. #include "trace.h"
  34. #include "qom/object.h"
  35. /*
  36. * Helper functions
  37. */
  38. static uint64_t mask_32bit_val(hwaddr addr, unsigned size, uint64_t val)
  39. {
  40. if (size == 8) {
  41. return val;
  42. }
  43. if (addr & 4) {
  44. val >>= 32;
  45. } else {
  46. val = (uint32_t) val;
  47. }
  48. return val;
  49. }
  50. static void put_val_in_int64(uint64_t *p, hwaddr addr, unsigned size,
  51. uint64_t val)
  52. {
  53. if (size == 8) {
  54. *p = val;
  55. } else if (size == 4) {
  56. if (addr & 4) {
  57. *p = ((*p << 32) >> 32) | (val << 32);
  58. } else {
  59. *p = ((*p >> 32) << 32) | (uint32_t) val;
  60. }
  61. }
  62. }
  63. static void put_val_in_arrary(uint64_t *array, hwaddr start_addr,
  64. hwaddr addr, unsigned size, uint64_t val)
  65. {
  66. int index;
  67. index = (addr - start_addr) / 8;
  68. put_val_in_int64(&array[index], addr, size, val);
  69. }
  70. /*
  71. * The Elroy PCI host bridge. We have at least 4 of those under Astro.
  72. */
  73. static MemTxResult elroy_chip_read_with_attrs(void *opaque, hwaddr addr,
  74. uint64_t *data, unsigned size,
  75. MemTxAttrs attrs)
  76. {
  77. MemTxResult ret = MEMTX_OK;
  78. ElroyState *s = opaque;
  79. uint64_t val = -1;
  80. int index;
  81. switch ((addr >> 3) << 3) {
  82. case 0x0008:
  83. val = 0x6000005; /* func_class */
  84. break;
  85. case 0x0058:
  86. /*
  87. * Scratch register, but firmware initializes it with the
  88. * PCI BUS number and Linux/HP-UX uses it then.
  89. */
  90. val = s->pci_bus_num;
  91. /* Upper byte holds the end of this bus number */
  92. val |= s->pci_bus_num << 8;
  93. break;
  94. case 0x0080:
  95. val = s->arb_mask; /* set ARB mask */
  96. break;
  97. case 0x0108:
  98. val = s->status_control;
  99. break;
  100. case 0x200 ... 0x250 - 1: /* LMMIO, GMMIO, WLMMIO, WGMMIO, ... */
  101. index = (addr - 0x200) / 8;
  102. val = s->mmio_base[index];
  103. break;
  104. case 0x0680:
  105. val = s->error_config;
  106. break;
  107. case 0x0688:
  108. val = 0; /* ERROR_STATUS */
  109. break;
  110. case 0x0800: /* IOSAPIC_REG_SELECT */
  111. val = s->iosapic_reg_select;
  112. break;
  113. case 0x0810: /* IOSAPIC_REG_WINDOW */
  114. switch (s->iosapic_reg_select) {
  115. case 0x01: /* IOSAPIC_REG_VERSION */
  116. val = (32 << 16) | 1; /* upper 16bit holds max entries */
  117. break;
  118. default:
  119. if (s->iosapic_reg_select < ARRAY_SIZE(s->iosapic_reg)) {
  120. val = s->iosapic_reg[s->iosapic_reg_select];
  121. } else {
  122. goto check_hf;
  123. }
  124. }
  125. trace_iosapic_reg_read(s->iosapic_reg_select, size, val);
  126. break;
  127. default:
  128. check_hf:
  129. if (s->status_control & HF_ENABLE) {
  130. val = 0;
  131. ret = MEMTX_DECODE_ERROR;
  132. } else {
  133. /* return -1ULL if HardFail is disabled */
  134. val = ~0;
  135. ret = MEMTX_OK;
  136. }
  137. }
  138. trace_elroy_read(addr, size, val);
  139. /* for 32-bit accesses mask return value */
  140. val = mask_32bit_val(addr, size, val);
  141. trace_astro_chip_read(addr, size, val);
  142. *data = val;
  143. return ret;
  144. }
  145. static MemTxResult elroy_chip_write_with_attrs(void *opaque, hwaddr addr,
  146. uint64_t val, unsigned size,
  147. MemTxAttrs attrs)
  148. {
  149. ElroyState *s = opaque;
  150. int i;
  151. trace_elroy_write(addr, size, val);
  152. switch ((addr >> 3) << 3) {
  153. case 0x000: /* PCI_ID & PCI_COMMAND_STATUS_REG */
  154. break;
  155. case 0x080:
  156. put_val_in_int64(&s->arb_mask, addr, size, val);
  157. break;
  158. case 0x0108:
  159. put_val_in_int64(&s->status_control, addr, size, val);
  160. break;
  161. case 0x200 ... 0x250 - 1: /* LMMIO, GMMIO, WLMMIO, WGMMIO, ... */
  162. put_val_in_arrary(s->mmio_base, 0x200, addr, size, val);
  163. break;
  164. case 0x300: /* ibase */
  165. case 0x308: /* imask */
  166. break;
  167. case 0x0680:
  168. put_val_in_int64(&s->error_config, addr, size, val);
  169. break;
  170. case 0x0800: /* IOSAPIC_REG_SELECT */
  171. s->iosapic_reg_select = val;
  172. break;
  173. case 0x0810: /* IOSAPIC_REG_WINDOW */
  174. trace_iosapic_reg_write(s->iosapic_reg_select, size, val);
  175. if (s->iosapic_reg_select < ARRAY_SIZE(s->iosapic_reg)) {
  176. s->iosapic_reg[s->iosapic_reg_select] = val;
  177. } else {
  178. goto check_hf;
  179. }
  180. break;
  181. case 0x0840: /* IOSAPIC_REG_EOI */
  182. val = le64_to_cpu(val);
  183. val &= 63;
  184. for (i = 0; i < ELROY_IRQS; i++) {
  185. if ((s->iosapic_reg[0x10 + 2 * i] & 63) == val) {
  186. s->ilr &= ~(1ull << i);
  187. }
  188. }
  189. break;
  190. default:
  191. check_hf:
  192. if (s->status_control & HF_ENABLE) {
  193. return MEMTX_DECODE_ERROR;
  194. }
  195. }
  196. return MEMTX_OK;
  197. }
  198. static const MemoryRegionOps elroy_chip_ops = {
  199. .read_with_attrs = elroy_chip_read_with_attrs,
  200. .write_with_attrs = elroy_chip_write_with_attrs,
  201. .endianness = DEVICE_LITTLE_ENDIAN,
  202. .valid = {
  203. .min_access_size = 4,
  204. .max_access_size = 8,
  205. },
  206. .impl = {
  207. .min_access_size = 4,
  208. .max_access_size = 8,
  209. },
  210. };
  211. /* Unlike pci_config_data_le_ops, no check of high bit set in config_reg. */
  212. static uint64_t elroy_config_data_read(void *opaque, hwaddr addr, unsigned len)
  213. {
  214. uint64_t val;
  215. PCIHostState *s = opaque;
  216. val = pci_data_read(s->bus, s->config_reg | (addr & 3), len);
  217. trace_elroy_pci_config_data_read(s->config_reg | (addr & 3), len, val);
  218. return val;
  219. }
  220. static void elroy_config_data_write(void *opaque, hwaddr addr,
  221. uint64_t val, unsigned len)
  222. {
  223. PCIHostState *s = opaque;
  224. pci_data_write(s->bus, s->config_reg | (addr & 3), val, len);
  225. trace_elroy_pci_config_data_write(s->config_reg | (addr & 3), len, val);
  226. }
  227. static const MemoryRegionOps elroy_config_data_ops = {
  228. .read = elroy_config_data_read,
  229. .write = elroy_config_data_write,
  230. .endianness = DEVICE_LITTLE_ENDIAN,
  231. };
  232. static uint64_t elroy_config_addr_read(void *opaque, hwaddr addr, unsigned len)
  233. {
  234. ElroyState *s = opaque;
  235. return s->config_reg_elroy;
  236. }
  237. static void elroy_config_addr_write(void *opaque, hwaddr addr,
  238. uint64_t val, unsigned len)
  239. {
  240. PCIHostState *s = opaque;
  241. ElroyState *es = opaque;
  242. es->config_reg_elroy = val; /* keep a copy of original value */
  243. s->config_reg = val;
  244. }
  245. static const MemoryRegionOps elroy_config_addr_ops = {
  246. .read = elroy_config_addr_read,
  247. .write = elroy_config_addr_write,
  248. .valid.min_access_size = 4,
  249. .valid.max_access_size = 8,
  250. .endianness = DEVICE_LITTLE_ENDIAN,
  251. };
  252. /* Handle PCI-to-system address translation. */
  253. static IOMMUTLBEntry astro_translate_iommu(IOMMUMemoryRegion *iommu,
  254. hwaddr addr,
  255. IOMMUAccessFlags flag,
  256. int iommu_idx)
  257. {
  258. AstroState *s = container_of(iommu, AstroState, iommu);
  259. hwaddr pdir_ptr, index, ibase;
  260. hwaddr addr_mask = 0xfff; /* 4k translation */
  261. uint64_t entry;
  262. #define IOVP_SHIFT 12 /* equals PAGE_SHIFT */
  263. #define PDIR_INDEX(iovp) ((iovp) >> IOVP_SHIFT)
  264. #define SBA_PDIR_VALID_BIT 0x8000000000000000ULL
  265. addr &= ~addr_mask;
  266. /*
  267. * Default translation: "32-bit PCI Addressing on 40-bit Runway".
  268. * For addresses in the 32-bit memory address range ... and then
  269. * language which not-coincidentally matches the PSW.W=0 mapping.
  270. */
  271. if (addr <= UINT32_MAX) {
  272. entry = hppa_abs_to_phys_pa2_w0(addr);
  273. } else {
  274. entry = addr;
  275. }
  276. /* "range enable" flag cleared? */
  277. if ((s->tlb_ibase & 1) == 0) {
  278. goto skip;
  279. }
  280. ibase = s->tlb_ibase & ~1ULL;
  281. if ((addr & s->tlb_imask) != ibase) {
  282. /* do not translate this one! */
  283. goto skip;
  284. }
  285. index = PDIR_INDEX(addr);
  286. pdir_ptr = s->tlb_pdir_base + index * sizeof(entry);
  287. entry = ldq_le_phys(&address_space_memory, pdir_ptr);
  288. if (!(entry & SBA_PDIR_VALID_BIT)) { /* I/O PDIR entry valid ? */
  289. /* failure */
  290. return (IOMMUTLBEntry) { .perm = IOMMU_NONE };
  291. }
  292. entry &= ~SBA_PDIR_VALID_BIT;
  293. entry >>= IOVP_SHIFT;
  294. entry <<= 12;
  295. skip:
  296. return (IOMMUTLBEntry) {
  297. .target_as = &address_space_memory,
  298. .iova = addr,
  299. .translated_addr = entry,
  300. .addr_mask = addr_mask,
  301. .perm = IOMMU_RW,
  302. };
  303. }
  304. static AddressSpace *elroy_pcihost_set_iommu(PCIBus *bus, void *opaque,
  305. int devfn)
  306. {
  307. ElroyState *s = opaque;
  308. return &s->astro->iommu_as;
  309. }
  310. static const PCIIOMMUOps elroy_pcihost_iommu_ops = {
  311. .get_address_space = elroy_pcihost_set_iommu,
  312. };
  313. /*
  314. * Encoding in IOSAPIC:
  315. * base_addr == 0xfffa0000, we want to get 0xa0ff0000.
  316. * eid 0x0ff00000 -> 0x00ff0000
  317. * id 0x000ff000 -> 0xff000000
  318. */
  319. #define SWIZZLE_HPA(a) \
  320. ((((a) & 0x0ff00000) >> 4) | (((a) & 0x000ff000) << 12))
  321. #define UNSWIZZLE_HPA(a) \
  322. (((((a) << 4) & 0x0ff00000) | (((a) >> 12) & 0x000ff000) | 0xf0000000))
  323. /* bits in the "low" I/O Sapic IRdT entry */
  324. #define IOSAPIC_IRDT_DISABLE 0x10000 /* if bit is set, mask this irq */
  325. #define IOSAPIC_IRDT_PO_LOW 0x02000
  326. #define IOSAPIC_IRDT_LEVEL_TRIG 0x08000
  327. #define IOSAPIC_IRDT_MODE_LPRI 0x00100
  328. #define CPU_IRQ_OFFSET 2
  329. static void elroy_set_irq(void *opaque, int irq, int level)
  330. {
  331. ElroyState *s = opaque;
  332. uint32_t bit;
  333. uint32_t old_ilr = s->ilr;
  334. hwaddr cpu_hpa;
  335. uint32_t val;
  336. val = s->iosapic_reg[0x10 + 2 * irq];
  337. cpu_hpa = s->iosapic_reg[0x11 + 2 * irq];
  338. /* low nibble of val has value to write into CPU irq reg */
  339. bit = 1u << (val & (ELROY_IRQS - 1));
  340. cpu_hpa = UNSWIZZLE_HPA(cpu_hpa);
  341. if (level && (!(val & IOSAPIC_IRDT_DISABLE)) && cpu_hpa) {
  342. uint32_t ena = bit & ~old_ilr;
  343. s->ilr = old_ilr | bit;
  344. if (ena != 0) {
  345. stl_be_phys(&address_space_memory, F_EXTEND(cpu_hpa), val & 63);
  346. }
  347. } else {
  348. s->ilr = old_ilr & ~bit;
  349. }
  350. }
  351. static int elroy_pci_map_irq(PCIDevice *d, int irq_num)
  352. {
  353. int slot = PCI_SLOT(d->devfn);
  354. assert(irq_num >= 0 && irq_num < ELROY_IRQS);
  355. return slot & (ELROY_IRQS - 1);
  356. }
  357. static void elroy_reset(DeviceState *dev)
  358. {
  359. ElroyState *s = ELROY_PCI_HOST_BRIDGE(dev);
  360. int irq;
  361. /*
  362. * Make sure to disable interrupts at reboot, otherwise the Linux kernel
  363. * serial8250_config_port() in drivers/tty/serial/8250/8250_port.c
  364. * will hang during autoconfig().
  365. */
  366. s->ilr = 0;
  367. for (irq = 0; irq < ELROY_IRQS; irq++) {
  368. s->iosapic_reg[0x10 + 2 * irq] = IOSAPIC_IRDT_PO_LOW |
  369. IOSAPIC_IRDT_LEVEL_TRIG | (irq + CPU_IRQ_OFFSET) |
  370. IOSAPIC_IRDT_DISABLE;
  371. s->iosapic_reg[0x11 + 2 * irq] = SWIZZLE_HPA(CPU_HPA);
  372. }
  373. }
  374. static void elroy_pcihost_init(Object *obj)
  375. {
  376. ElroyState *s = ELROY_PCI_HOST_BRIDGE(obj);
  377. PCIHostState *phb = PCI_HOST_BRIDGE(obj);
  378. SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
  379. /* Elroy config access from CPU. */
  380. memory_region_init_io(&s->this_mem, OBJECT(s), &elroy_chip_ops,
  381. s, "elroy", 0x2000);
  382. /* Elroy PCI config. */
  383. memory_region_init_io(&phb->conf_mem, OBJECT(phb),
  384. &elroy_config_addr_ops, DEVICE(s),
  385. "pci-conf-idx", 8);
  386. memory_region_init_io(&phb->data_mem, OBJECT(phb),
  387. &elroy_config_data_ops, DEVICE(s),
  388. "pci-conf-data", 8);
  389. memory_region_add_subregion(&s->this_mem, 0x40,
  390. &phb->conf_mem);
  391. memory_region_add_subregion(&s->this_mem, 0x48,
  392. &phb->data_mem);
  393. /* Elroy PCI bus memory. */
  394. memory_region_init(&s->pci_mmio, OBJECT(s), "pci-mmio", UINT64_MAX);
  395. memory_region_init_io(&s->pci_io, OBJECT(s), &unassigned_io_ops, obj,
  396. "pci-isa-mmio",
  397. ((uint32_t) IOS_DIST_BASE_SIZE) / ROPES_PER_IOC);
  398. phb->bus = pci_register_root_bus(DEVICE(s), "pci",
  399. elroy_set_irq, elroy_pci_map_irq, s,
  400. &s->pci_mmio, &s->pci_io,
  401. PCI_DEVFN(0, 0), ELROY_IRQS, TYPE_PCI_BUS);
  402. sysbus_init_mmio(sbd, &s->this_mem);
  403. qdev_init_gpio_in(DEVICE(obj), elroy_set_irq, ELROY_IRQS);
  404. }
  405. static const VMStateDescription vmstate_elroy = {
  406. .name = "Elroy",
  407. .version_id = 1,
  408. .minimum_version_id = 1,
  409. .fields = (const VMStateField[]) {
  410. VMSTATE_UINT64(hpa, ElroyState),
  411. VMSTATE_UINT32(pci_bus_num, ElroyState),
  412. VMSTATE_UINT64(config_address, ElroyState),
  413. VMSTATE_UINT64(config_reg_elroy, ElroyState),
  414. VMSTATE_UINT64(status_control, ElroyState),
  415. VMSTATE_UINT64(arb_mask, ElroyState),
  416. VMSTATE_UINT64_ARRAY(mmio_base, ElroyState, (0x0250 - 0x200) / 8),
  417. VMSTATE_UINT64(error_config, ElroyState),
  418. VMSTATE_UINT32(iosapic_reg_select, ElroyState),
  419. VMSTATE_UINT64_ARRAY(iosapic_reg, ElroyState, 0x20),
  420. VMSTATE_UINT32(ilr, ElroyState),
  421. VMSTATE_END_OF_LIST()
  422. }
  423. };
  424. static void elroy_pcihost_class_init(ObjectClass *klass, void *data)
  425. {
  426. DeviceClass *dc = DEVICE_CLASS(klass);
  427. device_class_set_legacy_reset(dc, elroy_reset);
  428. dc->vmsd = &vmstate_elroy;
  429. dc->user_creatable = false;
  430. }
  431. static const TypeInfo elroy_pcihost_info = {
  432. .name = TYPE_ELROY_PCI_HOST_BRIDGE,
  433. .parent = TYPE_PCI_HOST_BRIDGE,
  434. .instance_init = elroy_pcihost_init,
  435. .instance_size = sizeof(ElroyState),
  436. .class_init = elroy_pcihost_class_init,
  437. };
  438. static void elroy_register_types(void)
  439. {
  440. type_register_static(&elroy_pcihost_info);
  441. }
  442. type_init(elroy_register_types)
  443. static ElroyState *elroy_init(int num)
  444. {
  445. DeviceState *dev;
  446. dev = qdev_new(TYPE_ELROY_PCI_HOST_BRIDGE);
  447. dev->id = g_strdup_printf("elroy%d", num);
  448. sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
  449. return ELROY_PCI_HOST_BRIDGE(dev);
  450. }
  451. /*
  452. * Astro Runway chip.
  453. */
  454. static void adjust_LMMIO_DIRECT_mapping(AstroState *s, unsigned int reg_index)
  455. {
  456. MemoryRegion *lmmio_alias;
  457. unsigned int lmmio_index, map_route;
  458. hwaddr map_addr;
  459. uint32_t map_size;
  460. struct ElroyState *elroy;
  461. /* pointer to LMMIO_DIRECT entry */
  462. lmmio_index = reg_index / 3;
  463. lmmio_alias = &s->lmmio_direct[lmmio_index];
  464. map_addr = s->ioc_ranges[3 * lmmio_index + 0];
  465. map_size = s->ioc_ranges[3 * lmmio_index + 1];
  466. map_route = s->ioc_ranges[3 * lmmio_index + 2];
  467. /* find elroy to which this address is routed */
  468. map_route &= (ELROY_NUM - 1);
  469. elroy = s->elroy[map_route];
  470. if (lmmio_alias->enabled) {
  471. memory_region_set_enabled(lmmio_alias, false);
  472. }
  473. map_addr = F_EXTEND(map_addr);
  474. map_addr &= TARGET_PAGE_MASK;
  475. map_size = (~map_size) + 1;
  476. map_size &= TARGET_PAGE_MASK;
  477. /* exit if disabled or zero map size */
  478. if (!(map_addr & 1) || !map_size) {
  479. return;
  480. }
  481. if (!memory_region_size(lmmio_alias)) {
  482. memory_region_init_alias(lmmio_alias, OBJECT(elroy),
  483. "pci-lmmmio-alias", &elroy->pci_mmio,
  484. (uint32_t) map_addr, map_size);
  485. memory_region_add_subregion(get_system_memory(), map_addr,
  486. lmmio_alias);
  487. } else {
  488. memory_region_set_alias_offset(lmmio_alias, map_addr);
  489. memory_region_set_size(lmmio_alias, map_size);
  490. memory_region_set_enabled(lmmio_alias, true);
  491. }
  492. }
  493. static MemTxResult astro_chip_read_with_attrs(void *opaque, hwaddr addr,
  494. uint64_t *data, unsigned size,
  495. MemTxAttrs attrs)
  496. {
  497. AstroState *s = opaque;
  498. MemTxResult ret = MEMTX_OK;
  499. uint64_t val = -1;
  500. int index;
  501. switch ((addr >> 3) << 3) {
  502. /* R2I registers */
  503. case 0x0000: /* ID */
  504. val = (0x01 << 3) | 0x01ULL;
  505. break;
  506. case 0x0008: /* IOC_CTRL */
  507. val = s->ioc_ctrl;
  508. break;
  509. case 0x0010: /* TOC_CLIENT_ID */
  510. break;
  511. case 0x0030: /* HP-UX 10.20 and 11.11 reads it. No idea. */
  512. val = -1;
  513. break;
  514. case 0x0078: /* NetBSD reads 0x78 ? */
  515. val = -1;
  516. break;
  517. case 0x0300 ... 0x03d8: /* LMMIO_DIRECT0_BASE... */
  518. index = (addr - 0x300) / 8;
  519. val = s->ioc_ranges[index];
  520. break;
  521. case 0x10200:
  522. val = 0;
  523. break;
  524. case 0x10220:
  525. case 0x10230: /* HP-UX 11.11 reads it. No idea. */
  526. val = -1;
  527. break;
  528. case 0x22108: /* IOC STATUS_CONTROL */
  529. val = s->ioc_status_ctrl;
  530. break;
  531. case 0x20200 ... 0x20240 - 1: /* IOC Rope0_Control ... */
  532. index = (addr - 0x20200) / 8;
  533. val = s->ioc_rope_control[index];
  534. break;
  535. case 0x20040: /* IOC Rope config */
  536. val = s->ioc_rope_config;
  537. break;
  538. case 0x20050: /* IOC Rope debug */
  539. val = 0;
  540. break;
  541. case 0x20108: /* IOC STATUS_CONTROL */
  542. val = s->ioc_status_control;
  543. break;
  544. case 0x20310: /* IOC_PCOM */
  545. val = s->tlb_pcom;
  546. /* TODO: flush iommu */
  547. break;
  548. case 0x20400:
  549. val = s->ioc_flush_control;
  550. break;
  551. /* empty placeholders for non-existent elroys */
  552. #define EMPTY_PORT(x) case x: case x+8: val = 0; break; \
  553. case x+40: case x+48: val = UINT64_MAX; break;
  554. EMPTY_PORT(0x30000)
  555. EMPTY_PORT(0x32000)
  556. EMPTY_PORT(0x34000)
  557. EMPTY_PORT(0x36000)
  558. EMPTY_PORT(0x38000)
  559. EMPTY_PORT(0x3a000)
  560. EMPTY_PORT(0x3c000)
  561. EMPTY_PORT(0x3e000)
  562. #undef EMPTY_PORT
  563. default:
  564. val = 0;
  565. ret = MEMTX_DECODE_ERROR;
  566. }
  567. /* for 32-bit accesses mask return value */
  568. val = mask_32bit_val(addr, size, val);
  569. trace_astro_chip_read(addr, size, val);
  570. *data = val;
  571. return ret;
  572. }
  573. static MemTxResult astro_chip_write_with_attrs(void *opaque, hwaddr addr,
  574. uint64_t val, unsigned size,
  575. MemTxAttrs attrs)
  576. {
  577. MemTxResult ret = MEMTX_OK;
  578. AstroState *s = opaque;
  579. trace_astro_chip_write(addr, size, val);
  580. switch ((addr >> 3) << 3) {
  581. case 0x0000: /* ID */
  582. break;
  583. case 0x0008: /* IOC_CTRL */
  584. val &= 0x0ffffff;
  585. put_val_in_int64(&s->ioc_ctrl, addr, size, val);
  586. break;
  587. case 0x0010: /* TOC_CLIENT_ID */
  588. break;
  589. case 0x0030: /* HP-UX 10.20 and 11.11 reads it. No idea. */
  590. break;
  591. case 0x0300 ... 0x03d8 - 1: /* LMMIO_DIRECT0_BASE... */
  592. put_val_in_arrary(s->ioc_ranges, 0x300, addr, size, val);
  593. unsigned int index = (addr - 0x300) / 8;
  594. /* check if one of the 4 LMMIO_DIRECT regs, each using 3 entries. */
  595. if (index < LMMIO_DIRECT_RANGES * 3) {
  596. adjust_LMMIO_DIRECT_mapping(s, index);
  597. }
  598. break;
  599. case 0x10200:
  600. case 0x10220:
  601. case 0x10230: /* HP-UX 11.11 reads it. No idea. */
  602. break;
  603. case 0x20200 ... 0x20240 - 1: /* IOC Rope0_Control ... */
  604. put_val_in_arrary(s->ioc_rope_control, 0x20200, addr, size, val);
  605. break;
  606. case 0x20040: /* IOC Rope config */
  607. case 0x22040:
  608. put_val_in_int64(&s->ioc_rope_config, addr, size, val);
  609. break;
  610. case 0x20300:
  611. case 0x22300:
  612. put_val_in_int64(&s->tlb_ibase, addr, size, val);
  613. break;
  614. case 0x20308:
  615. case 0x22308:
  616. put_val_in_int64(&s->tlb_imask, addr, size, val);
  617. break;
  618. case 0x20310:
  619. case 0x22310:
  620. put_val_in_int64(&s->tlb_pcom, addr, size, val);
  621. /* TODO: flush iommu */
  622. break;
  623. case 0x20318:
  624. case 0x22318:
  625. put_val_in_int64(&s->tlb_tcnfg, addr, size, val);
  626. break;
  627. case 0x20320:
  628. case 0x22320:
  629. put_val_in_int64(&s->tlb_pdir_base, addr, size, val);
  630. break;
  631. case 0x22000: /* func_id */
  632. break;
  633. case 0x22008: /* func_class */
  634. break;
  635. case 0x22050: /* rope_debug */
  636. break;
  637. case 0x22108: /* IOC STATUS_CONTROL */
  638. put_val_in_int64(&s->ioc_status_ctrl, addr, size, val);
  639. break;
  640. /*
  641. * empty placeholders for non-existent elroys, e.g.
  642. * func_class, pci config & data
  643. */
  644. #define EMPTY_PORT(x) case x: case x+8: case x+0x40: case x+0x48:
  645. EMPTY_PORT(0x30000)
  646. EMPTY_PORT(0x32000)
  647. EMPTY_PORT(0x34000)
  648. EMPTY_PORT(0x36000)
  649. EMPTY_PORT(0x38000)
  650. EMPTY_PORT(0x3a000)
  651. EMPTY_PORT(0x3c000)
  652. EMPTY_PORT(0x3e000)
  653. break;
  654. #undef EMPTY_PORT
  655. default:
  656. ret = MEMTX_DECODE_ERROR;
  657. }
  658. return ret;
  659. }
  660. static const MemoryRegionOps astro_chip_ops = {
  661. .read_with_attrs = astro_chip_read_with_attrs,
  662. .write_with_attrs = astro_chip_write_with_attrs,
  663. .endianness = DEVICE_LITTLE_ENDIAN,
  664. .valid = {
  665. .min_access_size = 4,
  666. .max_access_size = 8,
  667. },
  668. .impl = {
  669. .min_access_size = 4,
  670. .max_access_size = 8,
  671. },
  672. };
  673. static const VMStateDescription vmstate_astro = {
  674. .name = "Astro",
  675. .version_id = 1,
  676. .minimum_version_id = 1,
  677. .fields = (const VMStateField[]) {
  678. VMSTATE_UINT64(ioc_ctrl, AstroState),
  679. VMSTATE_UINT64(ioc_status_ctrl, AstroState),
  680. VMSTATE_UINT64_ARRAY(ioc_ranges, AstroState, (0x03d8 - 0x300) / 8),
  681. VMSTATE_UINT64(ioc_rope_config, AstroState),
  682. VMSTATE_UINT64(ioc_status_control, AstroState),
  683. VMSTATE_UINT64(ioc_flush_control, AstroState),
  684. VMSTATE_UINT64_ARRAY(ioc_rope_control, AstroState, 8),
  685. VMSTATE_UINT64(tlb_ibase, AstroState),
  686. VMSTATE_UINT64(tlb_imask, AstroState),
  687. VMSTATE_UINT64(tlb_pcom, AstroState),
  688. VMSTATE_UINT64(tlb_tcnfg, AstroState),
  689. VMSTATE_UINT64(tlb_pdir_base, AstroState),
  690. VMSTATE_END_OF_LIST()
  691. }
  692. };
  693. static void astro_reset(DeviceState *dev)
  694. {
  695. AstroState *s = ASTRO_CHIP(dev);
  696. int i;
  697. s->ioc_ctrl = 0x29cf;
  698. s->ioc_rope_config = 0xc5f;
  699. s->ioc_flush_control = 0xb03;
  700. s->ioc_status_control = 0;
  701. memset(&s->ioc_rope_control, 0, sizeof(s->ioc_rope_control));
  702. /*
  703. * The SBA BASE/MASK registers control CPU -> IO routing.
  704. * The LBA BASE/MASK registers control IO -> System routing (in Elroy)
  705. */
  706. memset(&s->ioc_ranges, 0, sizeof(s->ioc_ranges));
  707. s->ioc_ranges[(0x360 - 0x300) / 8] = LMMIO_DIST_BASE_ADDR | 0x01; /* LMMIO_DIST_BASE (SBA) */
  708. s->ioc_ranges[(0x368 - 0x300) / 8] = 0xfc000000; /* LMMIO_DIST_MASK */
  709. s->ioc_ranges[(0x370 - 0x300) / 8] = 0; /* LMMIO_DIST_ROUTE */
  710. s->ioc_ranges[(0x390 - 0x300) / 8] = IOS_DIST_BASE_ADDR | 0x01; /* IOS_DIST_BASE */
  711. s->ioc_ranges[(0x398 - 0x300) / 8] = 0xffffff0000; /* IOS_DIST_MASK */
  712. s->ioc_ranges[(0x3a0 - 0x300) / 8] = 0x3400000000000000ULL; /* IOS_DIST_ROUTE */
  713. s->ioc_ranges[(0x3c0 - 0x300) / 8] = 0xfffee00000; /* IOS_DIRECT_BASE */
  714. s->ioc_ranges[(0x3c8 - 0x300) / 8] = 0xffffff0000; /* IOS_DIRECT_MASK */
  715. s->ioc_ranges[(0x3d0 - 0x300) / 8] = 0x0; /* IOS_DIRECT_ROUTE */
  716. s->tlb_ibase = 0;
  717. s->tlb_imask = 0;
  718. s->tlb_pcom = 0;
  719. s->tlb_tcnfg = 0;
  720. s->tlb_pdir_base = 0;
  721. for (i = 0; i < ELROY_NUM; i++) {
  722. elroy_reset(DEVICE(s->elroy[i]));
  723. }
  724. }
  725. static void astro_init(Object *obj)
  726. {
  727. }
  728. static void astro_realize(DeviceState *obj, Error **errp)
  729. {
  730. AstroState *s = ASTRO_CHIP(obj);
  731. SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
  732. int i;
  733. memory_region_init_io(&s->this_mem, OBJECT(s), &astro_chip_ops,
  734. s, "astro", 0x40000);
  735. sysbus_init_mmio(sbd, &s->this_mem);
  736. /* Host memory as seen from Elroys PCI side, via the IOMMU. */
  737. memory_region_init_iommu(&s->iommu, sizeof(s->iommu),
  738. TYPE_ASTRO_IOMMU_MEMORY_REGION, OBJECT(s),
  739. "iommu-astro", UINT64_MAX);
  740. address_space_init(&s->iommu_as, MEMORY_REGION(&s->iommu),
  741. "bm-pci");
  742. /* Create Elroys (PCI host bus chips). */
  743. for (i = 0; i < ELROY_NUM; i++) {
  744. static const int elroy_hpa_offsets[ELROY_NUM] = {
  745. 0x30000, 0x32000, 0x38000, 0x3c000 };
  746. static const char elroy_rope_nr[ELROY_NUM] = {
  747. 0, 1, 4, 6 }; /* busnum path, e.g. [10:6] */
  748. int addr_offset;
  749. ElroyState *elroy;
  750. hwaddr map_addr;
  751. uint64_t map_size;
  752. int rope;
  753. addr_offset = elroy_hpa_offsets[i];
  754. rope = elroy_rope_nr[i];
  755. elroy = elroy_init(i);
  756. s->elroy[i] = elroy;
  757. elroy->hpa = ASTRO_HPA + addr_offset;
  758. elroy->pci_bus_num = i;
  759. elroy->astro = s;
  760. /*
  761. * NOTE: we only allow PCI devices on first Elroy for now.
  762. * SeaBIOS will not find devices on the other busses.
  763. */
  764. if (i > 0) {
  765. qbus_mark_full(&PCI_HOST_BRIDGE(elroy)->bus->qbus);
  766. }
  767. /* map elroy config addresses into Astro space */
  768. memory_region_add_subregion(&s->this_mem, addr_offset,
  769. &elroy->this_mem);
  770. /* LMMIO */
  771. elroy->mmio_base[(0x0200 - 0x200) / 8] = 0xf0000001;
  772. elroy->mmio_base[(0x0208 - 0x200) / 8] = 0xf8000000;
  773. /* GMMIO */
  774. elroy->mmio_base[(0x0210 - 0x200) / 8] = 0x000000f800000001;
  775. elroy->mmio_base[(0x0218 - 0x200) / 8] = 0x000000ff80000000;
  776. /* WLMMIO */
  777. elroy->mmio_base[(0x0220 - 0x200) / 8] = 0xf0000001;
  778. elroy->mmio_base[(0x0228 - 0x200) / 8] = 0xf0000000;
  779. /* WGMMIO */
  780. elroy->mmio_base[(0x0230 - 0x200) / 8] = 0x000000f800000001;
  781. elroy->mmio_base[(0x0238 - 0x200) / 8] = 0x000000fc00000000;
  782. /* IOS_BASE */
  783. map_size = IOS_DIST_BASE_SIZE / ROPES_PER_IOC;
  784. elroy->mmio_base[(0x0240 - 0x200) / 8] = rope * map_size | 0x01;
  785. elroy->mmio_base[(0x0248 - 0x200) / 8] = 0x0000e000;
  786. /* map elroys mmio */
  787. map_size = LMMIO_DIST_BASE_SIZE / ROPES_PER_IOC;
  788. map_addr = F_EXTEND(LMMIO_DIST_BASE_ADDR + rope * map_size);
  789. memory_region_init_alias(&elroy->pci_mmio_alias, OBJECT(elroy),
  790. "pci-mmio-alias",
  791. &elroy->pci_mmio, (uint32_t) map_addr, map_size);
  792. memory_region_add_subregion(get_system_memory(), map_addr,
  793. &elroy->pci_mmio_alias);
  794. /* map elroys io */
  795. map_size = IOS_DIST_BASE_SIZE / ROPES_PER_IOC;
  796. map_addr = F_EXTEND(IOS_DIST_BASE_ADDR + rope * map_size);
  797. memory_region_add_subregion(get_system_memory(), map_addr,
  798. &elroy->pci_io);
  799. /* Host memory as seen from the PCI side, via the IOMMU. */
  800. pci_setup_iommu(PCI_HOST_BRIDGE(elroy)->bus, &elroy_pcihost_iommu_ops,
  801. elroy);
  802. }
  803. }
  804. static void astro_class_init(ObjectClass *klass, void *data)
  805. {
  806. DeviceClass *dc = DEVICE_CLASS(klass);
  807. device_class_set_legacy_reset(dc, astro_reset);
  808. dc->vmsd = &vmstate_astro;
  809. dc->realize = astro_realize;
  810. /*
  811. * astro with elroys are hard part of the newer PA2.0 machines and can not
  812. * be created without that hardware
  813. */
  814. dc->user_creatable = false;
  815. }
  816. static const TypeInfo astro_chip_info = {
  817. .name = TYPE_ASTRO_CHIP,
  818. .parent = TYPE_SYS_BUS_DEVICE,
  819. .instance_init = astro_init,
  820. .instance_size = sizeof(AstroState),
  821. .class_init = astro_class_init,
  822. };
  823. static void astro_iommu_memory_region_class_init(ObjectClass *klass,
  824. void *data)
  825. {
  826. IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass);
  827. imrc->translate = astro_translate_iommu;
  828. }
  829. static const TypeInfo astro_iommu_memory_region_info = {
  830. .parent = TYPE_IOMMU_MEMORY_REGION,
  831. .name = TYPE_ASTRO_IOMMU_MEMORY_REGION,
  832. .class_init = astro_iommu_memory_region_class_init,
  833. };
  834. static void astro_register_types(void)
  835. {
  836. type_register_static(&astro_chip_info);
  837. type_register_static(&astro_iommu_memory_region_info);
  838. }
  839. type_init(astro_register_types)