2 Copyright 1999, Be Incorporated. All Rights Reserved.
3 This file may be used under the terms of the Be Sample Code License.
7 Rudolf Cornelissen 10/2002-1/2006.
10 #define MODULE_BIT 0x00800000
16 static status_t
init_common(int the_fd
);
18 /* Initialization code shared between primary and cloned accelerants */
19 static status_t
init_common(int the_fd
)
22 nm_get_private_data gpd
;
24 // LOG not available from here to next LOG: NULL si
26 /* memorize the file descriptor */
28 /* set the magic number so the driver knows we're for real */
29 gpd
.magic
= NM_PRIVATE_DATA_MAGIC
;
30 /* contact driver and get a pointer to the registers and shared data */
31 result
= ioctl(fd
, NM_GET_PRIVATE_DATA
, &gpd
, sizeof(gpd
));
32 if (result
!= B_OK
) goto error0
;
34 /* clone the shared area for our use */
35 shared_info_area
= clone_area(DRIVER_PREFIX
" shared", (void **)&si
, B_ANY_ADDRESS
,
36 B_READ_AREA
| B_WRITE_AREA
, gpd
.shared_info_area
);
37 if (shared_info_area
< 0) {
38 result
= shared_info_area
;
41 // LOG is now available, si !NULL
42 LOG(4,("init_common: logmask 0x%08x, memory %dMB, hardcursor %d, usebios %d\n",
43 si
->settings
.logmask
, si
->settings
.memory
, si
->settings
.hardcursor
, si
->settings
.usebios
));
45 /* clone register area(s) */
48 /* we can't clone as no register area exists! */
49 LOG(2,("InitACC: Can't clone register area, integrated in framebuffer!\n"));
51 /* the kerneldriver already did some calcs for us */
52 regs
= si
->clone_bugfix_regs
;
58 /*Check for R4.5.0 and if it is running, use work around*/
59 if (si
->use_clone_bugfix
)
61 /*check for R4.5.0 bug and attempt to work around*/
62 LOG(2,("InitACC: Found R4.5.0 bug - attempting to work around\n"));
63 regs
= si
->clone_bugfix_regs
;
64 regs2
= si
->clone_bugfix_regs2
;
68 /* clone the memory mapped registers for our use - does not work on <4.5.2 (but is better this way)*/
69 regs_area
= clone_area(DRIVER_PREFIX
" regs", (void **)®s
, B_ANY_ADDRESS
,
70 B_READ_AREA
| B_WRITE_AREA
, si
->regs_area
);
78 regs2_area
= clone_area(DRIVER_PREFIX
" regs2", (void **)®s2
, B_ANY_ADDRESS
,
79 B_READ_AREA
| B_WRITE_AREA
, si
->regs2_area
);
89 /*FIXME - print dma addresses*/
90 //LOG(4,("DMA_virtual:%x\tDMA_physical:%x\tDMA_area:%x\n",si->dma_buffer,si->dma_buffer_pci,si->dma_buffer_area));
96 delete_area(regs_area
);
98 delete_area(shared_info_area
);
103 /* Clean up code shared between primary and cloned accelrants */
104 static void uninit_common(void)
106 /* release the memory mapped registers if they exist */
107 if (si
->ps
.card_type
> NM2093
)
109 delete_area(regs2_area
);
110 delete_area(regs_area
);
112 /* a little cheap paranoia */
115 /* release our copy of the shared info from the kernel driver */
116 delete_area(shared_info_area
);
117 /* more cheap paranoia */
122 Initialize the accelerant. the_fd is the file handle of the device (in
123 /dev/graphics) that has been opened by the app_server (or some test harness).
124 We need to determine if the kernel driver and the accelerant are compatible.
125 If they are, get the accelerant ready to handle other hook functions and
126 report success or failure.
128 status_t
INIT_ACCELERANT(int the_fd
)
131 int cnt
; //used for iteration through the overlay buffers
134 time_t now
= time (NULL
);
135 // LOG not available from here to next LOG: NULL si
136 MSG(("INIT_ACCELERANT: %s", ctime (&now
)));
139 /* note that we're the primary accelerant (accelerantIsClone is global) */
140 accelerantIsClone
= 0;
142 /* do the initialization common to both the primary and the clones */
143 result
= init_common(the_fd
);
145 /* bail out if the common initialization failed */
146 if (result
!= B_OK
) goto error0
;
147 // LOG now available: !NULL si
149 /* ensure that INIT_ACCELERANT is executed just once (copies should be clones) */
150 if (si
->accelerant_in_use
)
152 result
= B_NOT_ALLOWED
;
156 /* call the device specific init code */
157 result
= nm_general_powerup();
159 /* bail out if it failed */
160 if (result
!= B_OK
) goto error1
;
163 Now would be a good time to figure out what video modes your card supports.
164 We'll place the list of modes in another shared area so all of the copies
165 of the driver can see them. The primary copy of the accelerant (ie the one
166 initialized with this routine) will own the "one true copy" of the list.
167 Everybody else get's a read-only clone.
169 result
= create_mode_list();
176 Put the cursor at the start of the frame buffer. The typical 64x64 4 color
177 (black, white, transparent, inverse) takes up 1024 bytes of RAM.
179 /* Initialize the rest of the cursor information while we're here */
180 si
->cursor
.width
= 16;
181 si
->cursor
.height
= 16;
182 si
->cursor
.hot_x
= 0;
183 si
->cursor
.hot_y
= 0;
188 Put the frame buffer at the beginning of the cardRAM because the acc engine
189 does not support offsets, or we lack info to get that ability. We store this
190 info in a frame_buffer_config structure to make it convienient to return
191 to the app_server later.
193 si
->fbc
.frame_buffer
= si
->framebuffer
;
194 si
->fbc
.frame_buffer_dma
= si
->framebuffer_pci
;
196 /* count of issued parameters or commands */
197 si
->engine
.last_idle
= si
->engine
.count
= 0;
198 INIT_BEN(si
->engine
.lock
);
200 INIT_BEN(si
->overlay
.lock
);
201 for (cnt
= 0; cnt
< MAXBUFFERS
; cnt
++)
203 /* make sure overlay buffers are 'marked' as being free */
204 si
->overlay
.myBuffer
[cnt
].buffer
= NULL
;
205 si
->overlay
.myBuffer
[cnt
].buffer_dma
= NULL
;
207 /* make sure overlay unit is 'marked' as being free */
208 si
->overlay
.myToken
= NULL
;
210 /* note that overlay is not in use (for nm_bes_move_overlay()) */
211 si
->overlay
.active
= false;
213 /* bail out if something failed */
214 if (result
!= B_OK
) goto error1
;
216 /* initialise various cursor stuff*/
217 nm_crtc_cursor_init();
219 /* ensure cursor state */
222 /* ensure DPMS state */
223 si
->dpms_flags
= B_DPMS_ON
;
227 /* ensure that INIT_ACCELERANT won't be executed again (copies should be clones) */
228 si
->accelerant_in_use
= true;
233 Initialization failed after init_common() succeeded, so we need to clean
243 Return the number of bytes required to hold the information required
246 ssize_t
ACCELERANT_CLONE_INFO_SIZE(void)
249 Since we're passing the name of the device as the only required
250 info, return the size of the name buffer
252 return B_OS_NAME_LENGTH
;
257 Return the info required to clone the device. void *data points to
258 a buffer at least ACCELERANT_CLONE_INFO_SIZE() bytes in length.
260 void GET_ACCELERANT_CLONE_INFO(void *data
)
264 /* call the kernel driver to get the device name */
265 dn
.magic
= NM_PRIVATE_DATA_MAGIC
;
266 /* store the returned info directly into the passed buffer */
267 dn
.name
= (char *)data
;
268 ioctl(fd
, NM_DEVICE_NAME
, &dn
, sizeof(dn
));
272 Initialize a copy of the accelerant as a clone. void *data points to
273 a copy of the data returned by GET_ACCELERANT_CLONE_INFO().
275 status_t
CLONE_ACCELERANT(void *data
)
278 char path
[MAXPATHLEN
];
280 /* the data is the device name */
281 /* Note: the R4 graphics driver kit is in error here (missing trailing '/') */
282 strcpy(path
, "/dev/");
283 strcat(path
, (const char *)data
);
284 /* open the device, the permissions aren't important */
285 fd
= open(path
, B_READ_WRITE
);
288 /* we can't use LOG because we didn't get the shared_info struct.. */
292 sprintf (fname
, "/boot/home/" DRIVER_PREFIX
".accelerant.0.log");
293 myhand
=fopen(fname
,"a+");
294 fprintf(myhand
, "CLONE_ACCELERANT: couldn't open kerneldriver %s! Aborting.\n", path
);
297 /* abort with resultcode from open attempt on kerneldriver */
302 /* note that we're a clone accelerant */
303 accelerantIsClone
= 1;
305 /* call the shared initialization code */
306 result
= init_common(fd
);
308 /* bail out if the common initialization failed */
309 if (result
!= B_OK
) goto error1
;
311 /* ensure that INIT_ACCELERANT is executed first (i.e. primary accelerant exists) */
312 if (!(si
->accelerant_in_use
))
314 result
= B_NOT_ALLOWED
;
318 /* get shared area for display modes */
319 result
= my_mode_list_area
= clone_area(
320 DRIVER_PREFIX
" cloned display_modes",
321 (void **)&my_mode_list
,
326 if (result
< B_OK
) goto error2
;
329 LOG(4,("CLONE_ACCELERANT: cloning was succesfull.\n"));
335 /* free up the areas we cloned */
338 /* close the device we opened */
344 void UNINIT_ACCELERANT(void)
346 if (accelerantIsClone
)
348 LOG(4,("UNINIT_ACCELERANT: shutting down clone accelerant.\n"));
352 LOG(4,("UNINIT_ACCELERANT: shutting down primary accelerant.\n"));
354 /* delete benaphores ONLY if we are the primary accelerant */
355 DELETE_BEN(si
->engine
.lock
);
356 DELETE_BEN(si
->overlay
.lock
);
358 /* ensure that INIT_ACCELERANT can be executed again */
359 si
->accelerant_in_use
= false;
362 /* free our mode list area */
363 delete_area(my_mode_list_area
);
366 /* release our cloned data */
368 /* close the file handle ONLY if we're the clone */
369 if (accelerantIsClone
) close(fd
);