Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

bus_space(9) - amiga specific questions

5 views
Skip to first unread message

Radosław Kujawa

unread,
Feb 15, 2011, 8:56:40 PM2/15/11
to
Hello.

For a few months, as my time permits, I'm working to deepen my knowledge of the NetBSD kernel. Particularly of amiga and amigappc ports. There are still many cool devices which are not supported by NetBSD. I'd gladly change this situation by writing more drivers, but I feel that my foo is still not strong enough. I'd like someone verify my knowledge regarding bus_space on amiga port.

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?

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

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);

3. More about strides

The amiga_bus_stride_1 defines bus stride of "1 byte per word". Word means 2 bytes, right?

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" ?

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.

4. Misc

What does bus_space_handle_t really contain on amiga? I assume it's a pointer to the mapped (virtual) address? Is it normal for it to reside somewhere around 0x69xxx ?

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

--
Best regards,
Radoslaw Kujawa


--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-...@muc.de

Frank Wille

unread,
Feb 16, 2011, 5:31:19 AM2/16/11
to
On Wed, 16 Feb 2011 02:56:40 +0100
Rados?aw Kujawa <radosla...@c0ff33.net> 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

0 new messages