Port-powerpc archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

proposal: millicode



This proposal is primarily for OEA and OEA-like ppc machines, though there is
no reason much of this couldn't be adapted to ibm4xx machines as well.

Millicode, is the IBM term for routines that are implemented by the operating
system, and provide simple services to the OS, essentially, like a second layer
of firmware.

Millicode works similar to a shared code page.  You write some assembler code
to perform some kind of function, place it at a fixed physical offset in ram,
and then when you need to invoke it, you simply ba to that address.

Essentially, this allows us to remove certain if statements from the kernel, or
more importantly, #ifdefs from the kernel, where the outcome of the if is
allways the same on the running machine.

A simple example of this, might be some code where we do something like:

if (mfpvr() == MPC601) {
        do silliness;
} else {
        do normalstuff;
}

If this is in a codepath that gets called alot, we end up having to evaluate
that if over and over again, while, we know the answer is allways the same,
It's a 601.  So, early in startup, we have two functions, do_silliness() and
do_normalstuff(), and we check the PVR, and copy the appropriate one to 0x5000,
and just branch to it when we need to do that action.  This works essentially
the same as the vector tables we currently have for the external interrupts,
DSI's etc.

Why do I want to do this?

There are a few things I want to fix with this, some more pressing than others:

1) Right now, we can't compile a single kernel that supports both PPC_OEA and
bridge mode.  Most of the problem here lies in the FRAME_SETUP code, which
could be changed into millicode, and installed early during boot.  I consider
this one a must-have for ofppc, and probably for macppc G5 support. (there are
other problems here, but the FRAME_SETUP is the big one)

2) The 601 support relies on running around replacing certain instructions in
the kernel image with nops.  Many of these could be replaced with dual-version
millicode, and we could avoid the self-patching-kernel binary.

3) There might be cases where a certain processor would run much faster if we
could optimize some certain chunk of code for that processor.  This would allow
us to do so, and still have a GENERIC kernel that worked on all machines.  (or
provide different optimizations for each processor type for that chunk)

4) We could implement support for the gcc "common" target.  The common target
is a lowest common denominator of POWER, 601, and PowerPC, which produces code
that will run on all three CPUs.  It works by providing a set of six millicode
instructions that bridge the gap between the different architectures.  AIX
implements this, by placing the millicode at 0x3000, and then having libc stubs
that branch to that address.  If we ever have dreams of supporting compat_aix,
this would be a must have.

---
Tim Rightnour <root%garbled.net@localhost>
NetBSD: Free multi-architecture OS http://www.netbsd.org/
Genecys: Open Source 3D MMORPG: http://www.genecys.org/



Home | Main Index | Thread Index | Old Index