io.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Alpha IO and memory functions.
  4. */
  5. #include <linux/kernel.h>
  6. #include <linux/types.h>
  7. #include <linux/string.h>
  8. #include <linux/module.h>
  9. #include <asm/io.h>
  10. /* Out-of-line versions of the i/o routines that redirect into the
  11. platform-specific version. Note that "platform-specific" may mean
  12. "generic", which bumps through the machine vector. */
  13. unsigned int
  14. ioread8(const void __iomem *addr)
  15. {
  16. unsigned int ret;
  17. mb();
  18. ret = IO_CONCAT(__IO_PREFIX,ioread8)(addr);
  19. mb();
  20. return ret;
  21. }
  22. unsigned int ioread16(const void __iomem *addr)
  23. {
  24. unsigned int ret;
  25. mb();
  26. ret = IO_CONCAT(__IO_PREFIX,ioread16)(addr);
  27. mb();
  28. return ret;
  29. }
  30. unsigned int ioread32(const void __iomem *addr)
  31. {
  32. unsigned int ret;
  33. mb();
  34. ret = IO_CONCAT(__IO_PREFIX,ioread32)(addr);
  35. mb();
  36. return ret;
  37. }
  38. u64 ioread64(const void __iomem *addr)
  39. {
  40. unsigned int ret;
  41. mb();
  42. ret = IO_CONCAT(__IO_PREFIX,ioread64)(addr);
  43. mb();
  44. return ret;
  45. }
  46. void iowrite8(u8 b, void __iomem *addr)
  47. {
  48. mb();
  49. IO_CONCAT(__IO_PREFIX,iowrite8)(b, addr);
  50. }
  51. void iowrite16(u16 b, void __iomem *addr)
  52. {
  53. mb();
  54. IO_CONCAT(__IO_PREFIX,iowrite16)(b, addr);
  55. }
  56. void iowrite32(u32 b, void __iomem *addr)
  57. {
  58. mb();
  59. IO_CONCAT(__IO_PREFIX,iowrite32)(b, addr);
  60. }
  61. void iowrite64(u64 b, void __iomem *addr)
  62. {
  63. mb();
  64. IO_CONCAT(__IO_PREFIX,iowrite64)(b, addr);
  65. }
  66. EXPORT_SYMBOL(ioread8);
  67. EXPORT_SYMBOL(ioread16);
  68. EXPORT_SYMBOL(ioread32);
  69. EXPORT_SYMBOL(ioread64);
  70. EXPORT_SYMBOL(iowrite8);
  71. EXPORT_SYMBOL(iowrite16);
  72. EXPORT_SYMBOL(iowrite32);
  73. EXPORT_SYMBOL(iowrite64);
  74. u8 inb(unsigned long port)
  75. {
  76. return ioread8(ioport_map(port, 1));
  77. }
  78. u16 inw(unsigned long port)
  79. {
  80. return ioread16(ioport_map(port, 2));
  81. }
  82. u32 inl(unsigned long port)
  83. {
  84. return ioread32(ioport_map(port, 4));
  85. }
  86. void outb(u8 b, unsigned long port)
  87. {
  88. iowrite8(b, ioport_map(port, 1));
  89. }
  90. void outw(u16 b, unsigned long port)
  91. {
  92. iowrite16(b, ioport_map(port, 2));
  93. }
  94. void outl(u32 b, unsigned long port)
  95. {
  96. iowrite32(b, ioport_map(port, 4));
  97. }
  98. EXPORT_SYMBOL(inb);
  99. EXPORT_SYMBOL(inw);
  100. EXPORT_SYMBOL(inl);
  101. EXPORT_SYMBOL(outb);
  102. EXPORT_SYMBOL(outw);
  103. EXPORT_SYMBOL(outl);
  104. u8 __raw_readb(const volatile void __iomem *addr)
  105. {
  106. return IO_CONCAT(__IO_PREFIX,readb)(addr);
  107. }
  108. u16 __raw_readw(const volatile void __iomem *addr)
  109. {
  110. return IO_CONCAT(__IO_PREFIX,readw)(addr);
  111. }
  112. u32 __raw_readl(const volatile void __iomem *addr)
  113. {
  114. return IO_CONCAT(__IO_PREFIX,readl)(addr);
  115. }
  116. u64 __raw_readq(const volatile void __iomem *addr)
  117. {
  118. return IO_CONCAT(__IO_PREFIX,readq)(addr);
  119. }
  120. void __raw_writeb(u8 b, volatile void __iomem *addr)
  121. {
  122. IO_CONCAT(__IO_PREFIX,writeb)(b, addr);
  123. }
  124. void __raw_writew(u16 b, volatile void __iomem *addr)
  125. {
  126. IO_CONCAT(__IO_PREFIX,writew)(b, addr);
  127. }
  128. void __raw_writel(u32 b, volatile void __iomem *addr)
  129. {
  130. IO_CONCAT(__IO_PREFIX,writel)(b, addr);
  131. }
  132. void __raw_writeq(u64 b, volatile void __iomem *addr)
  133. {
  134. IO_CONCAT(__IO_PREFIX,writeq)(b, addr);
  135. }
  136. EXPORT_SYMBOL(__raw_readb);
  137. EXPORT_SYMBOL(__raw_readw);
  138. EXPORT_SYMBOL(__raw_readl);
  139. EXPORT_SYMBOL(__raw_readq);
  140. EXPORT_SYMBOL(__raw_writeb);
  141. EXPORT_SYMBOL(__raw_writew);
  142. EXPORT_SYMBOL(__raw_writel);
  143. EXPORT_SYMBOL(__raw_writeq);
  144. u8 readb(const volatile void __iomem *addr)
  145. {
  146. u8 ret;
  147. mb();
  148. ret = __raw_readb(addr);
  149. mb();
  150. return ret;
  151. }
  152. u16 readw(const volatile void __iomem *addr)
  153. {
  154. u16 ret;
  155. mb();
  156. ret = __raw_readw(addr);
  157. mb();
  158. return ret;
  159. }
  160. u32 readl(const volatile void __iomem *addr)
  161. {
  162. u32 ret;
  163. mb();
  164. ret = __raw_readl(addr);
  165. mb();
  166. return ret;
  167. }
  168. u64 readq(const volatile void __iomem *addr)
  169. {
  170. u64 ret;
  171. mb();
  172. ret = __raw_readq(addr);
  173. mb();
  174. return ret;
  175. }
  176. void writeb(u8 b, volatile void __iomem *addr)
  177. {
  178. mb();
  179. __raw_writeb(b, addr);
  180. }
  181. void writew(u16 b, volatile void __iomem *addr)
  182. {
  183. mb();
  184. __raw_writew(b, addr);
  185. }
  186. void writel(u32 b, volatile void __iomem *addr)
  187. {
  188. mb();
  189. __raw_writel(b, addr);
  190. }
  191. void writeq(u64 b, volatile void __iomem *addr)
  192. {
  193. mb();
  194. __raw_writeq(b, addr);
  195. }
  196. EXPORT_SYMBOL(readb);
  197. EXPORT_SYMBOL(readw);
  198. EXPORT_SYMBOL(readl);
  199. EXPORT_SYMBOL(readq);
  200. EXPORT_SYMBOL(writeb);
  201. EXPORT_SYMBOL(writew);
  202. EXPORT_SYMBOL(writel);
  203. EXPORT_SYMBOL(writeq);
  204. /*
  205. * The _relaxed functions must be ordered w.r.t. each other, but they don't
  206. * have to be ordered w.r.t. other memory accesses.
  207. */
  208. u8 readb_relaxed(const volatile void __iomem *addr)
  209. {
  210. mb();
  211. return __raw_readb(addr);
  212. }
  213. u16 readw_relaxed(const volatile void __iomem *addr)
  214. {
  215. mb();
  216. return __raw_readw(addr);
  217. }
  218. u32 readl_relaxed(const volatile void __iomem *addr)
  219. {
  220. mb();
  221. return __raw_readl(addr);
  222. }
  223. u64 readq_relaxed(const volatile void __iomem *addr)
  224. {
  225. mb();
  226. return __raw_readq(addr);
  227. }
  228. EXPORT_SYMBOL(readb_relaxed);
  229. EXPORT_SYMBOL(readw_relaxed);
  230. EXPORT_SYMBOL(readl_relaxed);
  231. EXPORT_SYMBOL(readq_relaxed);
  232. /*
  233. * Read COUNT 8-bit bytes from port PORT into memory starting at SRC.
  234. */
  235. void ioread8_rep(const void __iomem *port, void *dst, unsigned long count)
  236. {
  237. while ((unsigned long)dst & 0x3) {
  238. if (!count)
  239. return;
  240. count--;
  241. *(unsigned char *)dst = ioread8(port);
  242. dst += 1;
  243. }
  244. while (count >= 4) {
  245. unsigned int w;
  246. count -= 4;
  247. w = ioread8(port);
  248. w |= ioread8(port) << 8;
  249. w |= ioread8(port) << 16;
  250. w |= ioread8(port) << 24;
  251. *(unsigned int *)dst = w;
  252. dst += 4;
  253. }
  254. while (count) {
  255. --count;
  256. *(unsigned char *)dst = ioread8(port);
  257. dst += 1;
  258. }
  259. }
  260. void insb(unsigned long port, void *dst, unsigned long count)
  261. {
  262. ioread8_rep(ioport_map(port, 1), dst, count);
  263. }
  264. EXPORT_SYMBOL(ioread8_rep);
  265. EXPORT_SYMBOL(insb);
  266. /*
  267. * Read COUNT 16-bit words from port PORT into memory starting at
  268. * SRC. SRC must be at least short aligned. This is used by the
  269. * IDE driver to read disk sectors. Performance is important, but
  270. * the interfaces seems to be slow: just using the inlined version
  271. * of the inw() breaks things.
  272. */
  273. void ioread16_rep(const void __iomem *port, void *dst, unsigned long count)
  274. {
  275. if (unlikely((unsigned long)dst & 0x3)) {
  276. if (!count)
  277. return;
  278. BUG_ON((unsigned long)dst & 0x1);
  279. count--;
  280. *(unsigned short *)dst = ioread16(port);
  281. dst += 2;
  282. }
  283. while (count >= 2) {
  284. unsigned int w;
  285. count -= 2;
  286. w = ioread16(port);
  287. w |= ioread16(port) << 16;
  288. *(unsigned int *)dst = w;
  289. dst += 4;
  290. }
  291. if (count) {
  292. *(unsigned short*)dst = ioread16(port);
  293. }
  294. }
  295. void insw(unsigned long port, void *dst, unsigned long count)
  296. {
  297. ioread16_rep(ioport_map(port, 2), dst, count);
  298. }
  299. EXPORT_SYMBOL(ioread16_rep);
  300. EXPORT_SYMBOL(insw);
  301. /*
  302. * Read COUNT 32-bit words from port PORT into memory starting at
  303. * SRC. Now works with any alignment in SRC. Performance is important,
  304. * but the interfaces seems to be slow: just using the inlined version
  305. * of the inl() breaks things.
  306. */
  307. void ioread32_rep(const void __iomem *port, void *dst, unsigned long count)
  308. {
  309. if (unlikely((unsigned long)dst & 0x3)) {
  310. while (count--) {
  311. struct S { int x __attribute__((packed)); };
  312. ((struct S *)dst)->x = ioread32(port);
  313. dst += 4;
  314. }
  315. } else {
  316. /* Buffer 32-bit aligned. */
  317. while (count--) {
  318. *(unsigned int *)dst = ioread32(port);
  319. dst += 4;
  320. }
  321. }
  322. }
  323. void insl(unsigned long port, void *dst, unsigned long count)
  324. {
  325. ioread32_rep(ioport_map(port, 4), dst, count);
  326. }
  327. EXPORT_SYMBOL(ioread32_rep);
  328. EXPORT_SYMBOL(insl);
  329. /*
  330. * Like insb but in the opposite direction.
  331. * Don't worry as much about doing aligned memory transfers:
  332. * doing byte reads the "slow" way isn't nearly as slow as
  333. * doing byte writes the slow way (no r-m-w cycle).
  334. */
  335. void iowrite8_rep(void __iomem *port, const void *xsrc, unsigned long count)
  336. {
  337. const unsigned char *src = xsrc;
  338. while (count--)
  339. iowrite8(*src++, port);
  340. }
  341. void outsb(unsigned long port, const void *src, unsigned long count)
  342. {
  343. iowrite8_rep(ioport_map(port, 1), src, count);
  344. }
  345. EXPORT_SYMBOL(iowrite8_rep);
  346. EXPORT_SYMBOL(outsb);
  347. /*
  348. * Like insw but in the opposite direction. This is used by the IDE
  349. * driver to write disk sectors. Performance is important, but the
  350. * interfaces seems to be slow: just using the inlined version of the
  351. * outw() breaks things.
  352. */
  353. void iowrite16_rep(void __iomem *port, const void *src, unsigned long count)
  354. {
  355. if (unlikely((unsigned long)src & 0x3)) {
  356. if (!count)
  357. return;
  358. BUG_ON((unsigned long)src & 0x1);
  359. iowrite16(*(unsigned short *)src, port);
  360. src += 2;
  361. --count;
  362. }
  363. while (count >= 2) {
  364. unsigned int w;
  365. count -= 2;
  366. w = *(unsigned int *)src;
  367. src += 4;
  368. iowrite16(w >> 0, port);
  369. iowrite16(w >> 16, port);
  370. }
  371. if (count) {
  372. iowrite16(*(unsigned short *)src, port);
  373. }
  374. }
  375. void outsw(unsigned long port, const void *src, unsigned long count)
  376. {
  377. iowrite16_rep(ioport_map(port, 2), src, count);
  378. }
  379. EXPORT_SYMBOL(iowrite16_rep);
  380. EXPORT_SYMBOL(outsw);
  381. /*
  382. * Like insl but in the opposite direction. This is used by the IDE
  383. * driver to write disk sectors. Works with any alignment in SRC.
  384. * Performance is important, but the interfaces seems to be slow:
  385. * just using the inlined version of the outl() breaks things.
  386. */
  387. void iowrite32_rep(void __iomem *port, const void *src, unsigned long count)
  388. {
  389. if (unlikely((unsigned long)src & 0x3)) {
  390. while (count--) {
  391. struct S { int x __attribute__((packed)); };
  392. iowrite32(((struct S *)src)->x, port);
  393. src += 4;
  394. }
  395. } else {
  396. /* Buffer 32-bit aligned. */
  397. while (count--) {
  398. iowrite32(*(unsigned int *)src, port);
  399. src += 4;
  400. }
  401. }
  402. }
  403. void outsl(unsigned long port, const void *src, unsigned long count)
  404. {
  405. iowrite32_rep(ioport_map(port, 4), src, count);
  406. }
  407. EXPORT_SYMBOL(iowrite32_rep);
  408. EXPORT_SYMBOL(outsl);
  409. /*
  410. * Copy data from IO memory space to "real" memory space.
  411. * This needs to be optimized.
  412. */
  413. void memcpy_fromio(void *to, const volatile void __iomem *from, long count)
  414. {
  415. /* Optimize co-aligned transfers. Everything else gets handled
  416. a byte at a time. */
  417. if (count >= 8 && ((u64)to & 7) == ((u64)from & 7)) {
  418. count -= 8;
  419. do {
  420. *(u64 *)to = __raw_readq(from);
  421. count -= 8;
  422. to += 8;
  423. from += 8;
  424. } while (count >= 0);
  425. count += 8;
  426. }
  427. if (count >= 4 && ((u64)to & 3) == ((u64)from & 3)) {
  428. count -= 4;
  429. do {
  430. *(u32 *)to = __raw_readl(from);
  431. count -= 4;
  432. to += 4;
  433. from += 4;
  434. } while (count >= 0);
  435. count += 4;
  436. }
  437. if (count >= 2 && ((u64)to & 1) == ((u64)from & 1)) {
  438. count -= 2;
  439. do {
  440. *(u16 *)to = __raw_readw(from);
  441. count -= 2;
  442. to += 2;
  443. from += 2;
  444. } while (count >= 0);
  445. count += 2;
  446. }
  447. while (count > 0) {
  448. *(u8 *) to = __raw_readb(from);
  449. count--;
  450. to++;
  451. from++;
  452. }
  453. mb();
  454. }
  455. EXPORT_SYMBOL(memcpy_fromio);
  456. /*
  457. * Copy data from "real" memory space to IO memory space.
  458. * This needs to be optimized.
  459. */
  460. void memcpy_toio(volatile void __iomem *to, const void *from, long count)
  461. {
  462. /* Optimize co-aligned transfers. Everything else gets handled
  463. a byte at a time. */
  464. /* FIXME -- align FROM. */
  465. if (count >= 8 && ((u64)to & 7) == ((u64)from & 7)) {
  466. count -= 8;
  467. do {
  468. __raw_writeq(*(const u64 *)from, to);
  469. count -= 8;
  470. to += 8;
  471. from += 8;
  472. } while (count >= 0);
  473. count += 8;
  474. }
  475. if (count >= 4 && ((u64)to & 3) == ((u64)from & 3)) {
  476. count -= 4;
  477. do {
  478. __raw_writel(*(const u32 *)from, to);
  479. count -= 4;
  480. to += 4;
  481. from += 4;
  482. } while (count >= 0);
  483. count += 4;
  484. }
  485. if (count >= 2 && ((u64)to & 1) == ((u64)from & 1)) {
  486. count -= 2;
  487. do {
  488. __raw_writew(*(const u16 *)from, to);
  489. count -= 2;
  490. to += 2;
  491. from += 2;
  492. } while (count >= 0);
  493. count += 2;
  494. }
  495. while (count > 0) {
  496. __raw_writeb(*(const u8 *) from, to);
  497. count--;
  498. to++;
  499. from++;
  500. }
  501. mb();
  502. }
  503. EXPORT_SYMBOL(memcpy_toio);
  504. /*
  505. * "memset" on IO memory space.
  506. */
  507. void _memset_c_io(volatile void __iomem *to, unsigned long c, long count)
  508. {
  509. /* Handle any initial odd byte */
  510. if (count > 0 && ((u64)to & 1)) {
  511. __raw_writeb(c, to);
  512. to++;
  513. count--;
  514. }
  515. /* Handle any initial odd halfword */
  516. if (count >= 2 && ((u64)to & 2)) {
  517. __raw_writew(c, to);
  518. to += 2;
  519. count -= 2;
  520. }
  521. /* Handle any initial odd word */
  522. if (count >= 4 && ((u64)to & 4)) {
  523. __raw_writel(c, to);
  524. to += 4;
  525. count -= 4;
  526. }
  527. /* Handle all full-sized quadwords: we're aligned
  528. (or have a small count) */
  529. count -= 8;
  530. if (count >= 0) {
  531. do {
  532. __raw_writeq(c, to);
  533. to += 8;
  534. count -= 8;
  535. } while (count >= 0);
  536. }
  537. count += 8;
  538. /* The tail is word-aligned if we still have count >= 4 */
  539. if (count >= 4) {
  540. __raw_writel(c, to);
  541. to += 4;
  542. count -= 4;
  543. }
  544. /* The tail is half-word aligned if we have count >= 2 */
  545. if (count >= 2) {
  546. __raw_writew(c, to);
  547. to += 2;
  548. count -= 2;
  549. }
  550. /* And finally, one last byte.. */
  551. if (count) {
  552. __raw_writeb(c, to);
  553. }
  554. mb();
  555. }
  556. EXPORT_SYMBOL(_memset_c_io);
  557. /* A version of memcpy used by the vga console routines to move data around
  558. arbitrarily between screen and main memory. */
  559. void
  560. scr_memcpyw(u16 *d, const u16 *s, unsigned int count)
  561. {
  562. const u16 __iomem *ios = (const u16 __iomem *) s;
  563. u16 __iomem *iod = (u16 __iomem *) d;
  564. int s_isio = __is_ioaddr(s);
  565. int d_isio = __is_ioaddr(d);
  566. if (s_isio) {
  567. if (d_isio) {
  568. /* FIXME: Should handle unaligned ops and
  569. operation widening. */
  570. count /= 2;
  571. while (count--) {
  572. u16 tmp = __raw_readw(ios++);
  573. __raw_writew(tmp, iod++);
  574. }
  575. }
  576. else
  577. memcpy_fromio(d, ios, count);
  578. } else {
  579. if (d_isio)
  580. memcpy_toio(iod, s, count);
  581. else
  582. memcpy(d, s, count);
  583. }
  584. }
  585. EXPORT_SYMBOL(scr_memcpyw);
  586. void __iomem *ioport_map(unsigned long port, unsigned int size)
  587. {
  588. return IO_CONCAT(__IO_PREFIX,ioportmap) (port);
  589. }
  590. void ioport_unmap(void __iomem *addr)
  591. {
  592. }
  593. EXPORT_SYMBOL(ioport_map);
  594. EXPORT_SYMBOL(ioport_unmap);