PageRenderTime 47ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/hw/xfree86/os-support/bsd/arm_video.c

https://github.com/cubanismo/xserver
C | 628 lines | 442 code | 88 blank | 98 comment | 81 complexity | fcca34816d0846037f50cc63d9b62ffb MD5 | raw file
Possible License(s): MIT
  1. /*
  2. * Copyright 1992 by Rich Murphey <Rich@Rice.edu>
  3. * Copyright 1993 by David Wexelblat <dwex@goblin.org>
  4. *
  5. * Permission to use, copy, modify, distribute, and sell this software and its
  6. * documentation for any purpose is hereby granted without fee, provided that
  7. * the above copyright notice appear in all copies and that both that
  8. * copyright notice and this permission notice appear in supporting
  9. * documentation, and that the names of Rich Murphey and David Wexelblat
  10. * not be used in advertising or publicity pertaining to distribution of
  11. * the software without specific, written prior permission. Rich Murphey and
  12. * David Wexelblat make no representations about the suitability of this
  13. * software for any purpose. It is provided "as is" without express or
  14. * implied warranty.
  15. *
  16. * RICH MURPHEY AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD TO
  17. * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  18. * FITNESS, IN NO EVENT SHALL RICH MURPHEY OR DAVID WEXELBLAT BE LIABLE FOR
  19. * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  20. * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
  21. * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  22. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  23. *
  24. */
  25. /*
  26. * The ARM32 code here carries the following copyright:
  27. *
  28. * Copyright 1997
  29. * Digital Equipment Corporation. All rights reserved.
  30. * This software is furnished under license and may be used and copied only in
  31. * accordance with the following terms and conditions. Subject to these
  32. * conditions, you may download, copy, install, use, modify and distribute
  33. * this software in source and/or binary form. No title or ownership is
  34. * transferred hereby.
  35. *
  36. * 1) Any source code used, modified or distributed must reproduce and retain
  37. * this copyright notice and list of conditions as they appear in the
  38. * source file.
  39. *
  40. * 2) No right is granted to use any trade name, trademark, or logo of Digital
  41. * Equipment Corporation. Neither the "Digital Equipment Corporation"
  42. * name nor any trademark or logo of Digital Equipment Corporation may be
  43. * used to endorse or promote products derived from this software without
  44. * the prior written permission of Digital Equipment Corporation.
  45. *
  46. * 3) This software is provided "AS-IS" and any express or implied warranties,
  47. * including but not limited to, any implied warranties of merchantability,
  48. * fitness for a particular purpose, or non-infringement are disclaimed.
  49. * In no event shall DIGITAL be liable for any damages whatsoever, and in
  50. * particular, DIGITAL shall not be liable for special, indirect,
  51. * consequential, or incidental damages or damages for lost profits, loss
  52. * of revenue or loss of use, whether such damages arise in contract,
  53. * negligence, tort, under statute, in equity, at law or otherwise, even
  54. * if advised of the possibility of such damage.
  55. *
  56. */
  57. #ifdef HAVE_XORG_CONFIG_H
  58. #include <xorg-config.h>
  59. #endif
  60. #include <X11/X.h>
  61. #include "xf86.h"
  62. #include "xf86Priv.h"
  63. #include "xf86_OSlib.h"
  64. #include "xf86OSpriv.h"
  65. #ifdef __arm32__
  66. #include "machine/devmap.h"
  67. struct memAccess {
  68. int ioctl;
  69. struct map_info memInfo;
  70. void *regionVirtBase;
  71. Bool Checked;
  72. Bool OK;
  73. };
  74. static void *xf86MapInfoMap();
  75. static void xf86MapInfoUnmap();
  76. static struct memAccess *checkMapInfo();
  77. extern int vgaPhysLinearBase;
  78. /* A memAccess structure is needed for each possible region */
  79. struct memAccess vgaMemInfo = { CONSOLE_GET_MEM_INFO, NULL, NULL,
  80. FALSE, FALSE
  81. };
  82. struct memAccess linearMemInfo = { CONSOLE_GET_LINEAR_INFO, NULL, NULL,
  83. FALSE, FALSE
  84. };
  85. struct memAccess ioMemInfo = { CONSOLE_GET_IO_INFO, NULL, NULL,
  86. FALSE, FALSE
  87. };
  88. #endif /* __arm32__ */
  89. #if defined(__NetBSD__) && !defined(MAP_FILE)
  90. #define MAP_FLAGS MAP_SHARED
  91. #else
  92. #define MAP_FLAGS (MAP_FILE | MAP_SHARED)
  93. #endif
  94. #define BUS_BASE 0L
  95. #define BUS_BASE_BWX 0L
  96. /***************************************************************************/
  97. /* Video Memory Mapping section */
  98. /***************************************************************************/
  99. static Bool useDevMem = FALSE;
  100. static int devMemFd = -1;
  101. static void *mapVidMem(int, unsigned long, unsigned long, int);
  102. static void unmapVidMem(int, void *, unsigned long);
  103. /*
  104. * Check if /dev/mem can be mmap'd. If it can't print a warning when
  105. * "warn" is TRUE.
  106. */
  107. static void
  108. checkDevMem(Bool warn)
  109. {
  110. static Bool devMemChecked = FALSE;
  111. int fd;
  112. void *base;
  113. if (devMemChecked)
  114. return;
  115. devMemChecked = TRUE;
  116. if ((fd = open(DEV_MEM, O_RDWR)) >= 0) {
  117. /* Try to map a page at the VGA address */
  118. base = mmap((caddr_t) 0, 4096, PROT_READ | PROT_WRITE,
  119. MAP_FLAGS, fd, (off_t) 0xA0000 + BUS_BASE);
  120. if (base != MAP_FAILED) {
  121. munmap((caddr_t) base, 4096);
  122. devMemFd = fd;
  123. useDevMem = TRUE;
  124. return;
  125. }
  126. else {
  127. /* This should not happen */
  128. if (warn) {
  129. xf86Msg(X_WARNING, "checkDevMem: failed to mmap %s (%s)\n",
  130. DEV_MEM, strerror(errno));
  131. }
  132. useDevMem = FALSE;
  133. return;
  134. }
  135. }
  136. if (warn) {
  137. xf86Msg(X_WARNING, "checkDevMem: failed to open %s (%s)\n",
  138. DEV_MEM, strerror(errno));
  139. }
  140. useDevMem = FALSE;
  141. return;
  142. }
  143. void
  144. xf86OSInitVidMem(VidMemInfoPtr pVidMem)
  145. {
  146. checkDevMem(TRUE);
  147. pVidMem->linearSupported = useDevMem;
  148. pVidMem->mapMem = armMapVidMem;
  149. pVidMem->unmapVidMem = armUnmapVidMem;
  150. pVidMem->initialised = TRUE;
  151. }
  152. static void *
  153. mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
  154. {
  155. void *base;
  156. checkDevMem(FALSE);
  157. if (useDevMem) {
  158. if (devMemFd < 0) {
  159. FatalError("xf86MapVidMem: failed to open %s (%s)\n",
  160. DEV_MEM, strerror(errno));
  161. }
  162. base = mmap((caddr_t) 0, Size,
  163. (flags & VIDMEM_READONLY) ?
  164. PROT_READ : (PROT_READ | PROT_WRITE),
  165. MAP_FLAGS, devMemFd, (off_t) Base + BUS_BASE_BWX);
  166. if (base == MAP_FAILED) {
  167. FatalError("%s: could not mmap %s [s=%x,a=%x] (%s)\n",
  168. "xf86MapVidMem", DEV_MEM, Size, Base, strerror(errno));
  169. }
  170. return base;
  171. }
  172. /* else, mmap /dev/vga */
  173. if ((unsigned long) Base < 0xA0000 || (unsigned long) Base >= 0xC0000) {
  174. FatalError("%s: Address 0x%x outside allowable range\n",
  175. "xf86MapVidMem", Base);
  176. }
  177. base = mmap(0, Size,
  178. (flags & VIDMEM_READONLY) ?
  179. PROT_READ : (PROT_READ | PROT_WRITE),
  180. MAP_FLAGS, xf86Info.consoleFd, (unsigned long) Base - 0xA0000);
  181. if (base == MAP_FAILED) {
  182. FatalError("xf86MapVidMem: Could not mmap /dev/vga (%s)\n",
  183. strerror(errno));
  184. }
  185. return base;
  186. }
  187. static void
  188. unmapVidMem(int ScreenNum, void *Base, unsigned long Size)
  189. {
  190. munmap((caddr_t) Base, Size);
  191. }
  192. /*
  193. * Read BIOS via mmap()ing DEV_MEM
  194. */
  195. int
  196. xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf,
  197. int Len)
  198. {
  199. unsigned char *ptr;
  200. int psize;
  201. int mlen;
  202. checkDevMem(TRUE);
  203. if (devMemFd == -1) {
  204. return -1;
  205. }
  206. psize = getpagesize();
  207. Offset += Base & (psize - 1);
  208. Base &= ~(psize - 1);
  209. mlen = (Offset + Len + psize - 1) & ~(psize - 1);
  210. ptr = (unsigned char *) mmap((caddr_t) 0, mlen, PROT_READ,
  211. MAP_SHARED, devMemFd, (off_t) Base + BUS_BASE);
  212. if ((long) ptr == -1) {
  213. xf86Msg(X_WARNING,
  214. "xf86ReadBIOS: %s mmap[s=%x,a=%x,o=%x] failed (%s)\n",
  215. DEV_MEM, Len, Base, Offset, strerror(errno));
  216. return -1;
  217. }
  218. #ifdef DEBUG
  219. ErrorF("xf86ReadBIOS: BIOS at 0x%08x has signature 0x%04x\n",
  220. Base, ptr[0] | (ptr[1] << 8));
  221. #endif
  222. (void) memcpy(Buf, (void *) (ptr + Offset), Len);
  223. (void) munmap((caddr_t) ptr, mlen);
  224. #ifdef DEBUG
  225. xf86MsgVerb(X_INFO, 3, "xf86ReadBIOS(%x, %x, Buf, %x)"
  226. "-> %02x %02x %02x %02x...\n",
  227. Base, Offset, Len, Buf[0], Buf[1], Buf[2], Buf[3]);
  228. #endif
  229. return Len;
  230. }
  231. /* XXX This needs to be updated for the ND */
  232. /*
  233. ** Find out whether the console driver provides memory mapping information
  234. ** for the specified region and return the map_info pointer. Print a warning if required.
  235. */
  236. static struct memAccess *
  237. checkMapInfo(Bool warn, int Region)
  238. {
  239. struct memAccess *memAccP;
  240. switch (Region) {
  241. case VGA_REGION:
  242. memAccP = &vgaMemInfo;
  243. break;
  244. case LINEAR_REGION:
  245. memAccP = &linearMemInfo;
  246. break;
  247. case MMIO_REGION:
  248. memAccP = &ioMemInfo;
  249. break;
  250. default:
  251. return NULL;
  252. break;
  253. }
  254. if (!memAccP->Checked) {
  255. if (ioctl(xf86Info.consoleFd, memAccP->ioctl, &(memAccP->memInfo)) ==
  256. -1) {
  257. if (warn) {
  258. xf86Msg(X_WARNING,
  259. "checkMapInfo: failed to get map info for region %d\n\t(%s)\n",
  260. Region, strerror(errno));
  261. }
  262. }
  263. else {
  264. if (memAccP->memInfo.u.map_info_mmap.map_offset != MAP_INFO_UNKNOWN)
  265. memAccP->OK = TRUE;
  266. }
  267. memAccP->Checked = TRUE;
  268. }
  269. if (memAccP->OK) {
  270. return memAccP;
  271. }
  272. else {
  273. return NULL;
  274. }
  275. }
  276. static void *
  277. xf86MapInfoMap(struct memAccess *memInfoP, void *Base, unsigned long Size)
  278. {
  279. struct map_info *mapInfoP = &(memInfoP->memInfo);
  280. if (mapInfoP->u.map_info_mmap.map_size == MAP_INFO_UNKNOWN) {
  281. Size = (unsigned long) Base + Size;
  282. }
  283. else {
  284. Size = mapInfoP->u.map_info_mmap.map_size;
  285. }
  286. switch (mapInfoP->method) {
  287. case MAP_MMAP:
  288. /* Need to remap if size is unknown because we may not have
  289. mapped the whole region initially */
  290. if (memInfoP->regionVirtBase == NULL ||
  291. mapInfoP->u.map_info_mmap.map_size == MAP_INFO_UNKNOWN) {
  292. if ((memInfoP->regionVirtBase =
  293. mmap((caddr_t) 0,
  294. Size,
  295. PROT_READ | PROT_WRITE,
  296. MAP_SHARED,
  297. xf86Info.consoleFd,
  298. (unsigned long) mapInfoP->u.map_info_mmap.map_offset))
  299. == (void *) -1) {
  300. FatalError
  301. ("xf86MapInfoMap: Failed to map memory at 0x%x\n\t%s\n",
  302. mapInfoP->u.map_info_mmap.map_offset, strerror(errno));
  303. }
  304. if (mapInfoP->u.map_info_mmap.internal_offset > 0)
  305. memInfoP->regionVirtBase +=
  306. mapInfoP->u.map_info_mmap.internal_offset;
  307. }
  308. break;
  309. default:
  310. FatalError("xf86MapInfoMap: Unsuported mapping method\n");
  311. break;
  312. }
  313. return (void *) ((int) memInfoP->regionVirtBase + (int) Base);
  314. }
  315. static void
  316. xf86MapInfoUnmap(struct memAccess *memInfoP, unsigned long Size)
  317. {
  318. struct map_info *mapInfoP = &(memInfoP->memInfo);
  319. switch (mapInfoP->method) {
  320. case MAP_MMAP:
  321. if (memInfoP->regionVirtBase != NULL) {
  322. if (mapInfoP->u.map_info_mmap.map_size != MAP_INFO_UNKNOWN)
  323. Size = mapInfoP->u.map_info_mmap.map_size;
  324. munmap((caddr_t) memInfoP->regionVirtBase, Size);
  325. memInfoP->regionVirtBase = NULL;
  326. }
  327. break;
  328. default:
  329. FatalError("xf86MapInfoMap: Unsuported mapping method\n");
  330. break;
  331. }
  332. }
  333. static void *
  334. armMapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
  335. {
  336. struct memAccess *memInfoP;
  337. if ((memInfoP = checkMapInfo(FALSE, Region)) != NULL) {
  338. /*
  339. ** xf86 passes in a physical address offset from the start
  340. ** of physical memory, but xf86MapInfoMap expects an
  341. ** offset from the start of the specified region - it gets
  342. ** the physical address of the region from the display driver.
  343. */
  344. switch (Region) {
  345. case LINEAR_REGION:
  346. if (vgaPhysLinearBase) {
  347. Base -= vgaPhysLinearBase;
  348. }
  349. break;
  350. case VGA_REGION:
  351. Base -= 0xA0000;
  352. break;
  353. }
  354. base = xf86MapInfoMap(memInfoP, Base, Size);
  355. return base;
  356. }
  357. return mapVidMem(ScreenNum, Base, Size, flags);
  358. }
  359. static void
  360. armUnmapVidMem(int ScreenNum, void *Base, unsigned long Size)
  361. {
  362. struct memAccess *memInfoP;
  363. if ((memInfoP = checkMapInfo(FALSE, Region)) != NULL) {
  364. xf86MapInfoUnmap(memInfoP, Base, Size);
  365. }
  366. unmapVidMem(ScreenNum, Base, Size);
  367. }
  368. #ifdef USE_DEV_IO
  369. static int IoFd = -1;
  370. Bool
  371. xf86EnableIO()
  372. {
  373. if (IoFd >= 0)
  374. return TRUE;
  375. if ((IoFd = open("/dev/io", O_RDWR)) == -1) {
  376. xf86Msg(X_WARNING, "xf86EnableIO: "
  377. "Failed to open /dev/io for extended I/O\n");
  378. return FALSE;
  379. }
  380. return TRUE;
  381. }
  382. void
  383. xf86DisableIO()
  384. {
  385. if (IoFd < 0)
  386. return;
  387. close(IoFd);
  388. IoFd = -1;
  389. return;
  390. }
  391. #endif
  392. #if defined(USE_ARC_MMAP) || defined(__arm32__)
  393. Bool
  394. xf86EnableIO()
  395. {
  396. int fd;
  397. void *base;
  398. if (ExtendedEnabled)
  399. return TRUE;
  400. if ((fd = open("/dev/ttyC0", O_RDWR)) >= 0) {
  401. /* Try to map a page at the pccons I/O space */
  402. base = (void *) mmap((caddr_t) 0, 65536, PROT_READ | PROT_WRITE,
  403. MAP_FLAGS, fd, (off_t) 0x0000);
  404. if (base != (void *) -1) {
  405. IOPortBase = base;
  406. }
  407. else {
  408. xf86Msg(X_WARNING, "EnableIO: failed to mmap %s (%s)\n",
  409. "/dev/ttyC0", strerror(errno));
  410. return FALSE;
  411. }
  412. }
  413. else {
  414. xf86Msg("EnableIO: failed to open %s (%s)\n",
  415. "/dev/ttyC0", strerror(errno));
  416. return FALSE;
  417. }
  418. ExtendedEnabled = TRUE;
  419. return TRUE;
  420. }
  421. void
  422. xf86DisableIO()
  423. {
  424. return;
  425. }
  426. #endif /* USE_ARC_MMAP */
  427. #if 0
  428. /*
  429. * XXX This is here for reference. It needs to be handled differently for the
  430. * ND.
  431. */
  432. #if defined(USE_ARC_MMAP) || defined(__arm32__)
  433. #ifdef USE_ARM32_MMAP
  434. #define DEV_MEM_IOBASE 0x43000000
  435. #endif
  436. static Bool ScreenEnabled[MAXSCREENS];
  437. static Bool ExtendedEnabled = FALSE;
  438. static Bool InitDone = FALSE;
  439. Bool
  440. xf86EnableIOPorts(ScreenNum)
  441. int ScreenNum;
  442. {
  443. int i;
  444. int fd;
  445. void *base;
  446. #ifdef __arm32__
  447. struct memAccess *memInfoP;
  448. int *Size;
  449. #endif
  450. ScreenEnabled[ScreenNum] = TRUE;
  451. if (ExtendedEnabled)
  452. return TRUE;
  453. #ifdef USE_ARC_MMAP
  454. if ((fd = open("/dev/ttyC0", O_RDWR)) >= 0) {
  455. /* Try to map a page at the pccons I/O space */
  456. base = (void *) mmap((caddr_t) 0, 65536, PROT_READ | PROT_WRITE,
  457. MAP_FLAGS, fd, (off_t) 0x0000);
  458. if (base != (void *) -1) {
  459. IOPortBase = base;
  460. }
  461. else {
  462. xf86Msg(X_ERROR,
  463. "EnableIOPorts: failed to mmap %s (%s)\n",
  464. "/dev/ttyC0", strerror(errno));
  465. }
  466. }
  467. else {
  468. xf86Msg(X_ERROR, "EnableIOPorts: failed to open %s (%s)\n",
  469. "/dev/ttyC0", strerror(errno));
  470. }
  471. #endif
  472. #ifdef __arm32__
  473. IOPortBase = (unsigned int) -1;
  474. if ((memInfoP = checkMapInfo(TRUE, MMIO_REGION)) != NULL) {
  475. /*
  476. * xf86MapInfoMap maps an offset from the start of video IO
  477. * space (e.g. 0x3B0), but IOPortBase is expected to map to
  478. * physical address 0x000, so subtract the start of video I/O
  479. * space from the result. This is safe for now becase we
  480. * actually mmap the start of the page, then the start of video
  481. * I/O space is added as an internal offset.
  482. */
  483. IOPortBase = (unsigned int) xf86MapInfoMap(memInfoP, (caddr_t) 0x0, 0L)
  484. - memInfoP->memInfo.u.map_info_mmap.internal_offset;
  485. ExtendedEnabled = TRUE;
  486. return TRUE;
  487. }
  488. #ifdef USE_ARM32_MMAP
  489. checkDevMem(TRUE);
  490. if (devMemFd >= 0 && useDevMem) {
  491. base = (void *) mmap((caddr_t) 0, 0x400, PROT_READ | PROT_WRITE,
  492. MAP_FLAGS, devMemFd, (off_t) DEV_MEM_IOBASE);
  493. if (base != (void *) -1)
  494. IOPortBase = (unsigned int) base;
  495. }
  496. if (IOPortBase == (unsigned int) -1) {
  497. xf86Msg(X_WARNING,
  498. "xf86EnableIOPorts: failed to open mem device or map IO base. \n\
  499. Make sure you have the Aperture Driver installed, or a kernel built with the INSECURE option\n");
  500. return FALSE;
  501. }
  502. #else
  503. /* We don't have the IOBASE, so we can't map the address */
  504. xf86Msg(X_WARNING,
  505. "xf86EnableIOPorts: failed to open mem device or map IO base. \n\
  506. Try building the server with USE_ARM32_MMAP defined\n");
  507. return FALSE;
  508. #endif
  509. #endif
  510. ExtendedEnabled = TRUE;
  511. return TRUE;
  512. }
  513. void
  514. xf86DisableIOPorts(ScreenNum)
  515. int ScreenNum;
  516. {
  517. int i;
  518. #ifdef __arm32__
  519. struct memAccess *memInfoP;
  520. #endif
  521. ScreenEnabled[ScreenNum] = FALSE;
  522. #ifdef __arm32__
  523. if ((memInfoP = checkMapInfo(FALSE, MMIO_REGION)) != NULL) {
  524. xf86MapInfoUnmap(memInfoP, 0);
  525. }
  526. #endif
  527. #ifdef USE_ARM32_MMAP
  528. if (!ExtendedEnabled)
  529. return;
  530. for (i = 0; i < MAXSCREENS; i++)
  531. if (ScreenEnabled[i])
  532. return;
  533. munmap((caddr_t) IOPortBase, 0x400);
  534. IOPortBase = (unsigned int) -1;
  535. ExtendedEnabled = FALSE;
  536. #endif
  537. return;
  538. }
  539. #endif /* USE_ARC_MMAP || USE_ARM32_MMAP */
  540. #endif