Port-amiga archive

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

Re: bus_space(9) - amiga specific questions



On Wed, 16 Feb 2011 02:56:40 +0100
Rados?aw Kujawa <radoslaw.kujawa%c0ff33.net@localhost> wrote:

> 1. Mapping the bus space
> 
> Lets assume that hardware has two interesting registers, at 0xdff1f0
> and 0xdff1f4. The registers are 16-bit. I'd write the following code
> to map it:
> 
> #define FOOHW_BASE    0xdff1f0
> #define REG0_OFF              0x0
> #define REG1_OFF              0x1 /* actually 0x4 but accessed
> #using stride_4 */
> struct bus_space_tag  foo_bst;
> bus_space_tag_t               foo_iot;
> bus_space_handle_t    foo_ioh;
> 
> foo_bst.base = (u_long) ztwomap(FOOHW_BASE);
> foo_bst.absm = &amiga_bus_stride_4; 
> foo_iot = &foo_bst;
> 
> bus_space_map(foo_iot, 0, 4, 0, foo_ioh);
> 
> Is the above code correct? 

It would work, but could be improved.


> Should bus_space_map argument 3 (size) be divided by stride? Or
> should I specify "real" size there?

No. Address and size specifications in bus_space(9) functions always
refer to the virtual bus space. So when the stride is 4, an address of
1 refers to byte-offset 4, and a size of 1 equals 4 bytes.

So correct would be
  bus_space_map(foo_iot, 0, 2, 0, foo_ioh)
because you want to map two registers in the space from 0xdff1f0 to 0xdff1f8.
Size 2 * Stride 4 covers a bus space of 8 bytes.

As your driver doesn't depend on any MI code you could also use the
normal amiga_bus_stride_1 and access the space byte-wise.

You could even do completely without bus spaces and just operate on the
ztwomapped address, but I guess it is cleaner to use them in all new code.


> 2. Writing/reading the registers
> 
> If I wanted to read 0xdff1f0 and then 0xdff1f4, I'd write:
> uint16_t reg0 = bus_space_read_2(foo_iot, foo_ioh, REG0_OFF); 
> uint16_t reg1 = bus_space_read_2(foo_iot, foo_ioh, REG1_OFF); 

Yes.


> 3. More about strides
> 
> The amiga_bus_stride_1 defines bus stride of "1 byte per word". Word
> means 2 bytes, right?

No. This could be a typo. Should be "1 byte per byte"?
The amiga_bus_stride_1 describes the normal register layout without holes
(like the custom chip registers, but unlike the CIA register map).

Bus space address 1 refers to byte-offset 1.
Bus space address 2 refers to byte-offset 2.


> Additionally, amiga_bus_stride_2 defines bus stride of 1 byte per 2
> words. The comment in amiga_bus_simple_2word.c again says "1 byte per
> word" but I guess that is an error and it should be "1 byte per 2
> words" ?

No. "1 byte per word" would be correct, when a word is seen as a 16-bit
M68k word. With a stride of 2 you got:

Bus space address 1 refers to byte-offset 2.
Bus space address 2 refers to byte-offset 4.


> Also, amiga_bus_stride_4 defines bus stride of "1 byte per long", as
> comment states. On an amiga 2 words equals 1 long (32-bit), but
> amiga_bus_stride_4 is defined as a method operating on words, so that
> would be 1 byte per 4 words? I'm really confused, I always thought
> it's 1 byte per 4 bytes, but now I'm not really sure.

It's not as complicated as you think. The stride is just a multiplicator
for bus space addresses and sizes.

And a bus space doesn't enforce a fixed size for the registers therein.
You are always free to access 8-bit, 16-bit or 32-bit registers with the
appropriate bus_space(9) functions (although you should avoid unaligned
accesses on the M68k architecture).

On the Amiga port the size argument is even completely ignored, when
mapping a bus space. The PowerPC ports, OTOH, remember bus space allocations
to avoid overlapping bus_space_map calls.

For completeness, when using amiga_bus_stride4:
Bus space address 1 refers to byte-offset 4.
Bus space address 2 refers to byte-offset 8.


> 4. Misc
> 
> What does bus_space_handle_t really contain on amiga? I assume it's a
> pointer to the mapped (virtual) address?

Yes. But you should never take any assumptions about the real contents of
a bus_space_handle_t. It's an abstract type to allow MI code.


> Is it normal for it to reside somewhere around 0x69xxx ?

Probably. That's the kernel virtual address, which you got from ztwomap().

Unlike PowerPC, which does direct VA==PA mapping using the BATs, the Amiga
port (maybe all M68k ports) uses the MMU to map all interesting physical
memory regions into a contiguous space, starting somewhere at 0 or 0x2000.
Refer to start_c() in amiga_init.c.

The kernel virtual address space should be something like this:

NetBSD kernel
configdevs + memlists
lwp0uarea
Kernel segment table
Kernel page tables
CHIPMEMADDR (mapped Chip RAM)
ZTWOMEMADDR (mapped Zorro2 RAM) 
CIAADDR (mapped 0xbfc000 - 0xc00000)
ZTWOROMADDR (mapped 0xd80000 - 0xf80000)
Zorro3 space...?

This whole block lives approximately between the virtual address of 0x0
and 0x80000. So an address of 0x69xxx is quite ok.

My guess is that it has to be done like that, because the M68k has no BAT 
registers. And mapping the whole address space VA==PA wastes too much page
table entries.


> Can I use physical addresses to read or write data to registers when
> in DDB?

I doubt that. AFAIK ddb is running in kernel virtual address space.


-- 
Frank Wille


Home | Main Index | Thread Index | Old Index