Subject: New Internal Video Survey
To: None <port-mac68k@NetBSD.ORG>
From: M.R. Zucca <mrz5149@cs.rit.edu>
List: port-mac68k
Date: 06/05/1996 01:48:55
MacBSD Internal Video Survey "2.0"
----------------------------------

** Internal Video?

Recently, complete NuBus card video support was added to MacBSD. This means
that if you have a NuBus card you can most likely get color video, ability to
switch between modes on the fly in BSD, color palette manipulation, etc.
Well, I'd like to add that same support for "internal video" which is the
built-in or on-board video on your Mac.

There are a few problems associated with this. One of them is the difference
between the types of video on each machine. This problem was solved on the
NuBus cards by using the driver routines included in the NuBus card's ROM.
This same approach is possible with internal video but it is a little bit
more tricky to pull off. With NuBus cards, you just check what slot the card
is in, ask it for its ROM and you're set. With internal video, you have to
find the driver code hidden somewhere in the Macintosh ROMs rather
than on a card's ROM. Worse still, each Mac has its code in a slightly
different place.

Another problem is the fact that in order for a driver to work it must be
able to access hardware registers that make it possible to control the video
hardware. With a NuBus card the hardware registers are located in the card's
pre-defined address space based on which slot the card is plugged in to.
With internal video, the hardware registers could be anywhere.

While this may seem to be a bleak situation it is solvable as we shall soon see.


** What's This Survey?

Since there are so many different kinds of internal video I need to collect
information about each type. So, I have made a little survey that you can fill
in if you have the technical expertise that may give me insight into finding
a general solution.

I'm hoping that I can find a pattern amongst the different kinds of video so
that I can make a general solution to the problem or at least a pretty flexible
solution.


** Prerequisites

Some internal videos are still not supported in their "basic" stage yet. That
is, they currently must work with a serial console or risk crashing. This is
a wholely different problem. The support I'm working on is more "advanced"
and it requires that your video be supported at least at a "basic" level.
This is fairly simple to solve, however. Basically, the problem boils down
to two things or a combination thereof:

1. Your screen base address isn't being mapped in.
This means that NetBSD doesn't know where screen memory starts on your machine.
It assumes zero or some other value and *KABLOOIE* your system crashes. You
or someone else must add the video base address to the NetBSD boot process.

2. The body of screen memory is not being mapped in at all.
This means that NetBSD knows where your screen starts but the body of screen
memory isn't mapped in so it thinks your screen is either really small or
assumes that some other area is screen memory and pokes into it when it tries
to display something. This is basically the same problem as above. Your
machine's screen mapping must be added to the kernel boot-up process.

You can get tech specs for your machine on a D E V E L O P bookmark CD, from
Apple, from printed tech notes from Apple, or some other source. These specs
usually include a rough memory map that includes where screen memory starts
and how big it is.


** What You Need

To gather the kind of information I need requires that you are not afraid of
looking around in memory, can understand 680x0 assembly, and are generally
proficient with MacsBug or are willing to learn any of former skills :)

There are a few handy programs that I'm going to mention later.

Slots:
ftp://puma.bevd.blacksburg.va.us/pub/NetBSD/cray-ymp/util/Slots.bin
You'll need this to gather some basic information.

Rommie:
This program is kind of useful if you really plan on hacking around inside
the ROMs. The down side is that it doesn't work on every machine and for
the purposes of the video driver code, the resource dump that it makes is
useless. I won't bother with the URL since you really don't need it here but
I'd though I'd metion it.

ResEdit with Code Editor and MacsBug are also a must. If you have The Debugger
or Resourcerer please sell me your copy at a student rate of $10 ;-) ;-) ;-)

If the above URL doesn't work, check out any Apple developer mirror.


** The Actual Survey

Machine:
ROM Start:
ROM End:
Driver:
Has An Entry In The System File:
Slot:
Virtual Controller Base:
Virtual Controller Range:
Physical Controller Base:
Physical Controller Range:
ROM SResource Location:
Other Info:
Your E-Mail Address:


** How To Fill Out The Survey
Some entries are obvious, like the Machine type, but I'll go through the whole
thing below with tips on how to get the information.  When you've got it
filled in, please trim off everything but the survey itself and E-Mail it to
me. (mrz5149@cs.rit.edu)

If you can't fill in the whole thing, don't worry. Just send as much as you can.

****** MAKE SURE YOU'RE USING 32 BIT ADDRESSING!!! *******


** Survey Entry Explanations/Tips

* Machine
Just fill in the type of machine you have. If you're using a Performa, please
fill in the machine it is "analogous" to as well. In other words, some Performas
aren't much more than regular Macs with a Performa sticker on them.

* ROM Start
Sometimes you can get this through tech specs, etc. but the easiest way to do
it is by going into MacsBug and typing the "mbug" command. This lists a bunch
of information. Amongst all the junk there is "gROMStart" which should have
the address of the start of ROM

* ROM End
You can get this almost the same way as ROM Start. Just look at the gROMEnd
field after you type "mbug" in MacsBug

* Driver
Fill in the name of the video driver that internal video uses. The easiest way
to do this is to run "Slots". Look for windows with slot information about
".Display_Video_Apple_" something. Usually internal video is in Slot 0 or Slot E
but on some PowerBooks there are actually two internal videos, one for the
LCD screen and one for the video port on the back of the machine. I'll talk
about how to handle such cases later. If you're using a machine with both
internal video and a NuBus card make sure you don't confuse the NuBus card with
the internal video. Such cards can fall in slots numbered hex 9,A,B,C,D or E.
E is kind of an exception in this case but odds are that you probably don't
have a card in there.

Don't assume that because a driver name starts with ".Display_Video_Apple_" that
it is internal video because you can end up with cases like
".Display_Video_Apple_TFB" which is the Toby Frame Buffer NuBus card.

* Has An Entry In The System File
Now that you know the Driver name, look at a copy of your System file with
ResEdit and see if there is a copy of the driver in the system file by
checking out the DRVR resource. If it's there, enter "yes" otherwise, enter
"no". Do this part after you fill out the next entry "Slot" since you don't
want to do all this and then run Slots again. :)

* Slot
When you run Slots and fill out the "Driver" part, fill this field in with
the Slot the driver was in. Most of the time the slot is 0 or E.

* Virtual Controller Base
This part is tough and really requires that you be able to understand raw
assembly code. There are two ways to go, try them both if you can since one
may give more insight in ways the other didn't. First some preliminaries about
finding your way around a video driver:

- Video Driver anatomy
>From the few drivers that I've seen there is a sort standard way each driver
is layed out. Here's a general picture:

---
Standard Driver Header
---
DrvrOpen
---
A Procedure or two with no name
---
DrvrCtrl
---
DrvrStatus
---
A Bunch of procedures with no name
---
Data (Maybe standard gamma or palette info)
---

This is not fixed but often shuffled around. Many drivers put the data at
the start of the file. One of the ways to tell data apart from code is to
look for a great deal of "ori", "dc" instructions or instructions that don't
seem to belong in the code you're looking at (like QuickTime traps or something)

I've also noticed that code like "DrvrCtrl" parts of the driver don't do any
real work themselves but often call one of the nameless routines that follow
them.

- What We're Looking For
As I said before, the driver has to control the video hardware by putting values
into hardware registers. These are located somewhere in memory. Since the
internal video hardware isn't likely to move Apple has opted to hard-code
the address of these registers in the driver. The base address is a frequently
reoccuring address. It is often added off of to access other addresses.

For instance, on my IIvx the virtual base address is 0x0CEC. This address is
often used to find other aparently critical addresses like 0x0CEC + 0x10

- The ResEdit Way
To do it this way you need to have put "yes" in "Has An Entry In The System
File". In this case, open up a copy of the system file and locate the driver
in the DRVR resource. Open it. If you're not using CODE editor, you're looking
at raw hex. Nobody's *that* tough. Go and get CODE editor. :)

Look around for a frequently used, hard-coded address. Odds are that it is
low in memory like around 0B00-0F00.

To make your job easier, look for such values being used in "MOVEA.L"
instructions. Like:

MOVEA.L    A3,0CEC

Don't be fooled by things like

MOVE.L     (A3)+20,A4

The 20 is not an address but an offset. This sort of thing might be useful in
the next section, though.

Where to begin? Try looking at some of the nameless routines following DrvrOpen
sections. You should see things like SlotVInstall instructions. This is probably
where the video hardware is actually initialized for opening or closed for
closing. Another good area to check is following Ctrl or Status calls since
these do alot of the leg work.

Try your best to run through the code as though you were actually calling the
routine. Make some assumptions and you might end up with a right answer.

- The MacsBug Way
This is much tougher than the ResEdit method but it is really the only
way you can do it if your driver isn't in the System.

First, you need to locate where the driver is in memory. You can do this by
doing a "drvr" command. Locate your driver in the mix and look for the
start address under the "Drvr at" column.

Start disassembling at this address and try to proceed like you would in the
ResEdit method. It's a little harder here since you don't have CODE Editor's
Anon's but you can get sort of an equivalent using the "ir" command in
MacsBug. This will disassemble until the next "rts" instruction which is usually
where a routine ends.

* Virtual Controller Range
This is very similar to the step above but slightly more challenging. Once you
think you've found the base address try to examine the code and look for places
where values are added to it to access other hardware registers. This is harder
because the base address is often just placed in an address register and passed
around. For instance, the IIvx driver places its 0CEC address into A3 and does
alot of:

MOVE.L     (A3)+10,#20

where the address is manipulated indirectly. Use the offset values like "+10"
above to see if you can figure a range of values the driver uses.

Another thing that helps with this is to drop into MacsBug and look at the
values around the base address. Then change bit depths and look at that same
area. What's changed? Do this will all kinds of combinations and you might be
able to figure out a range.

* Physical Controller Base and Physical Controller Range [OPTIONAL]
These fields are completely optional since the tools that you need to find
them easily are not really publicly available. In fact, I don't even have such
tools! The other reason is that I'm pretty sure I'm not going to use them in my
first attempt but I might consider using them later on if I can figure out an
easy, public method, of finding them.

In the previous cases you're looking for a group of addresses that
the driver wants. These are "virtual" addresses in that the ROMs or the system
has mapped high memory hardware addresses into low memory addresses for the
driver. You need the virtual addresses since the driver expects them but the
"real" addresses that they represent are also important if I ever make a
ROM-Independant solution like the video driver in PowerPC Linux on MACH.

Anyway, the easiest way to do this is to walk the page table and look for
the addresses in the address range you found in the "virtual" section.
This requires a tool like Jasik's debugger or dumping the page table before
locore does any serious damage to it when BSD boots.

An added bonus of this is that you can see if your virtual addresses make sense
and correct them if they don't. Reasoning: If you know where I/O space is on
your machine (check out the tech docs) odds are that the video controller
absolute hardware addresses are located there. You can then see what addresses
are mapped in your logical address range and confirm which ones are mapped into
Hardware I/O space.

* ROM SResource Location
This one's pretty easy...sort of. Do a search of you ROMs with MacsBug by
looking for the name of your video driver. Use the "f" command as follows

f [ROM start] [ROM end - ROM start] "Video_Apple_*"

Where [ROM start] is the start address of your ROM, [ROM end - ROM start] is
the size of your ROM (usually something like "ffffff") and the * is the last
part of your driver name.

This might be in a few spots. Try looking at the latest one. What we're
looking for here is something that looks like an SResource. In other words,
look for information that looks like the stuff Slots regurgitated at you
when you were looking for the name of the driver. If you disassemble this region
you should eventually come across the driver code which should be haunting your
sleep right about now :)

You might have to back off a few hundred addresses once MacsBug shows you
what you told it to look for. I found that just prior to the SResource
there was filler which was essentially a copyright message and the developer's
initials.

Fill in a range or a guestimate as to the start of the SResource. If you can
figure out what the exact start is, great!

* Other Info
Fill in any other discoveries you made about your internal video along the way.

* Your E-Mail Address
Guess what this is for :)


** A Sample Complete Form
This is just a sample (I faked up the Physical stuff so don't rely on it)

Machine: IIvx
ROM Start: 0x40800000
ROM End: 0x408FFFFF
Driver: .Display_Video_Apple_Brazil
Has An Entry In The System File: Yes
Slot: 0
Virtual Controller Base: 0x0CEC
Virtual Controller Range: 0x0CEC - 0x0E00
Physical Controller Base: 0x50803AFE - Clut  0x50803DDE - Controller
Physical Controller Range: 0x50803AFE - 0x50803BA0  0x50803DDE - 0x50803DED
ROM SResource Location: 0x408FE8B4
Other Info: None
Your E-Mail Address: mrz5149@cs.rit.edu


** Handling Powerbooks or other machines with multiple internal videos.

Some Powerbooks are kind of strange in that they have two different internal
video; one for the LCD screen and one for the video port on the back of the
machine. Basically, you have twice the work to do if you're in this situation.
Odds are, the internal video is on Slot 0 and the external video is on Slot E.
If you're lazy, just send me the Slot 0 info. Otherwise send me the information
on the following slightly modified survey:

Machine:
ROM Start:
ROM End:
* Internal Video
Driver:
Has An Entry In The System File:
Slot: 0
Virtual Controller Base:
Virtual Controller Range:
Physical Controller Base:
Physical Controller Range:
ROM SResource Location:
Other Info: None
* External Video
Driver:
Has An Entry In The System File:
Slot: 0
Virtual Controller Base:
Virtual Controller Range:
Physical Controller Base:
Physical Controller Range:
ROM SResource Location:
Other Info: None
Your E-Mail Address:


** What's The Plan?
The basic principle behind getting MacBSD to support Internal video is pretty
simple:

- Get locore to preserve the virtual controller address range at boot
- At attach time, search for the fake SResource and find the driver code in it
- Get the ioctl handling code to call the ROM Driver routines

This isn't too bad thanks to the NuBus video team's efforts. Much of the work
is already done! In fact, it may be possible to make "grand unified" video code
as is being done with the serial driver.

Of course, most of the tricky stuff comes in even before I deal with calling
Mac code.


** Hopeful Assumptions
Here's some basic ideas/assumptions I've got going:

- Internal video is almost always on Slot 0 or Slot E

- The video controllers on all the machines map to low mem in and around the
0B00 through 0E00 range. I would imagine that Apple did something like this
so that driver code could be recycled. Also, this low memory area might be
set aside for just the purpose of video controllers and other hardware so that
their respective logical hardware addresses would always be acessable regardless
of whether 24 or 32 bit addressing was on.

- The faked-up SResource for the video driver is after the last ROM package
or at the bottom of ROM. I noticed that _Package5 was the last one on my ROM
and that between _Package5 and the fake SResource there was some filler.
Chances are that the filler was to make it so that the fake SResource was
at the very end of the ROM. I *REALLY* hope this is true for all the ROMs or
at least partially true. Right now, it's my only hope for a heuristic to find
the SResource and, in turn, the driver code. Otherwise I'll have to hard code
a search based on Machine or ROM type.

- The current NuBus video code is a good start. Odds are that once I have the
mapping and all the other stuff right, the internal video code can be handled
as a special case of the NuBus code. It is an SResource after all! Just write
a different attach routine and we're in business.


** Interesting Side Effects/Problems

- Handling machines with both kinds of video. Lets say I have a NuBus card and
internal video or a Powerbook with a monitor on it. Which one gets to be
grf0 so that X comes up on the right screen? I think that this may have to
be a feature added to the booter. Perhaps X can use a different grf as the
root? I don't have multiple monitors so I have no idea. (This may change.
I may be able to pick up a cheap video card so I can test out such theories!)

- Machines with dual internal video and a search heuristic. If my original
hunch about the SResource being at the bottom of ROM is correct, odds are that
the machines with dual internal video will have both SResources at the bottom
of ROM. I must make sure to get both and not just one!

** End notes/Comments
I hope this document is helpful and I hope that I can gather plenty of info.

Have patience. I'm squeezing this project in between my day job, sleep, and
a slim social life. :) :)

Good Hunting!

_______________________________________________________________________
 Michael Zucca - mrz5149@rit.cs.rit.edu - http://www.rit.edu/~mrz5149/
 "I will choose a path that's clear. I will choose Freewill. "
  --Rush, Freewill
_______________________________________________________________________