6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Sep 29, 2024 2:14 am

All times are UTC




Post new topic Reply to topic  [ 10 posts ] 
Author Message
PostPosted: Sun Aug 08, 2010 5:36 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
I'm opening a discussion here because the idea is very much in flux.

Code:


PROBLEM: Any 65SIB device can appear at any address.

WHY THIS IS A PROBLEM: Human-interface devices (HIDs), like keyboards, LCD displays, etc. are required so that humans can use the system. But, if booting from ROM, the firmware has no way of knowing where these HIDs are located.

PROPOSED SOLUTION: Let each peripheral (optionally) support a means of identifying to the host system which kind of device it is.

IMPLICATIONS: Hardware peripherals trade some minor complexity for the flexibility of "just working" with most systems.


Configuration space is treated as a special-purpose address space. That is, you can read any byte from, and if supported, write any byte to, configuration space. Issue: should we employ existing eeprom/flash protocols to support this behavior? Having the ability to write individual bytes would be very much appreciated, for reasons I hope to illustrate below, which suggests we should instead consider RAM-based protocols instead.

Configuration space can be any size, but must be at least big enough to contain the following data structure:

Code:
Address  Read/Write  Description
    $00     R        Configuration space version (= 0)


This field must be zero, for only one version exists at the time of this writing. This one byte determines how all other bytes are laid out in memory.

Code:
Address  Read/Write  Description
    $01     R        Number of protocols this peripheral supports (0 < x < 255)


I define a "protocol" as the specific set of commands and responses supported by a normally selected peripheral. These include your LCD interface protocols, MMC memory protocols, etc.

Many devices support more than one protocol. For example, by definition, all SD media are also MMC media, but the reverse is not true. Hence, an intelligent SD media device would list that it supports 2 protocols: the MMC protocol, and the SD extensions there-to.

Another example would be a PS/2 keyboard adapter which is capable of producing plain-ASCII output, raw PS/2 scancodes, or (perhaps for development purposes) USB scancodes as well.

A value of 0 or 255 is meaningless at this time; any device indicating 0 or 255 supported protocols should be considered either dumb or absent (you're just reading a byte formed from the 65SIB's pull-up or pull-down resistor on the MISO line; you'll need to take the computer operator's word that there is, in fact, a real device on this address) or defective. Use this peripheral at your own risk.

Code:
Address  Read/Write  Description
    $02     R        Byte pointer to first protocol ID


$02 points to the first protocol ID in configuration space. As you might expect, the first byte must appear somewhere in the range $..04 to $..FF.

Protocol IDs are UUIDs; see http://en.wikipedia.org/wiki/Universall ... identifier . I opted for this approach because I don't feel like administering a central authority doling ID ranges out. If anyone has ideas for something better, I'm open to suggestions.

For example, an array of three protocols might look like:

Code:
$0080  DE AD BE EF FE ED FA CE - 01 02 03 04 05 06 07 08
$0090  01 02 03 04 05 06 07 08 - FE ED FA CE DE AD BE EF
$00A0  DE AD FA CE FE ED BE EF - AA 55 AA 55 55 AA 55 AA


where UUID {DEADBEEF-FEED-FACE-0102-030405060708} might refer to MMC memory protocol, {01020304-0506-0708-FEED-FACEDEADBEEF} might refer to SecureDigital extensions, and {DEADFACE-FEED-BEEF-AA55-AA5555AA55AA} might refer to proprietary extensions aiding in debugging.

Code:
Address  Read/Write  Description
$04-$07     R        Maximum device bits per second data transfer rate on 65SIB bus.
$08-$0B     R        Maximum configuration bits per second data transfer rate on 65SIB bus.


The minimum supported bits per second for either device or configuration selection is 0 bps. If your peripheral cannot handle this, then it's fundamentally incompatible with 65SIB by definition -- use such devices at your own risk. (Note that the 0bps requirement comes from the configuration protocol itself.)

All 65SIB devices must be able to handle at least 1000 bits per second. Conversely, if you do not know a device's maximum throughput, you are advised to query this information at a rate not to exceed 1000bps before attempting higher data rates. (The master must learn to walk before it can run. ;-) ).

Code:
Address  Read/Write  Description
$0C-$0F     R        Minimum latency between bus transactions for device.
$10-$13     R        Maximum latency between bus transactions for device.
$14-$17     R        Minimum latency between bus transactions for config.
$18-$1B     R        Maximum latency between bus transactions for config.


These should be fairly self-explanatory, I'd think. Time units are in nanoseconds, thus permitting over four second latencies between adjacent yet related transactions. A value of $FFFFFFFF implies infinity.

Code:
Address  Read/Write  Description
$1C-$1F     R        Model ID (chosen exclusively by the vendor)
$20-$2F     R        Vendor UUID.


Self-explanatory.

Code:
Address  Read/Write  Description
$30-$3F     R        Currently unused (read as zero).


Self-explanatory.

Code:


PROBLEM: Not all protocols inherit from some base specification.

WHY THIS IS A PROBLEM: For example, IBM PS/2 keyboard scancodes are completely incompatible with USB keyboard scancodes. And, sometimes, you just plain want simplicity in life, where plain-ASCII is all you need.

PROPOSED SOLUTION: Permit the master to configure the peripheral, as required, which protocol it wants to use.

IMPLICATIONS: Requires that the master be able to write into configuration space to issue commands to a configurator. The command set to use must remain stable across all classes of devices attached. All commands must end in finite time.

Code:
Address  Read/Write  Description
    $30     R/W      Command Byte


The command byte is composed of two fields:

Code:
+---+---+---+---+---+---+---+---+
| F |          command          |
+---+---+---+---+---+---+---+---+
  |               |
  |               +--------------  A value between $00-$7F
  |                                requesting the configurator
  |                                to take some action.
  |
  +------------------------------  0: Request completed (with or without error)
                                   1: Request in progress.


After writing relevant parameters into configuration space first, the master writes a command code with bit 7 set into location $30. It then will poll location $30 until bit 7 is clear.

Command $00 is, by definition for backward compatibility, no-operation.

Code:
Address  Read/Write  Description
$31-$37     R        Unused (read as zero)
$38-$39     R/W      Start of command parameters (16-bit configuration space)
$38-$3B     R/W      Start of command parameters (32-bit configuration space)
$38-$3F     R/W      Start of command parameters (64-bit configuration space)


Self-explanatory, but with one quirk:

You can detect the size of the configuration address space by filling in $38-$3F with $FF bytes. When you read these pointers back, you may find some of the address bits set to 0, indicating unused/unsupported address bits. For example, if you read back $00000000000FFF after writing $FFFFFFFFFFFFFFFF, you know only 4K of configuration space exists.

In the context of selecting the protocol to support, I define the following:

Command $01: query current protocol. The parameter block looks like this:
Code:
$00-$0F  UUID of the protocol to query support for (set by master).
    $10  $FF if supported; $00 otherwise (set by slave).


Command $02: set current protocol. The parameter block looks like the above, except that the indicated UUID is selected as the current protocol. The master must poll on address $30 to wait for this operation to complete, since changing protocols could conceivably take some time. Parameter byte $10 is ignored.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Aug 08, 2010 6:35 pm 
Offline

Joined: Thu Jul 26, 2007 4:46 pm
Posts: 105
A few thoughts:

1) Are you sure that a byte pointer is the best way to reference the UUID list? Would making it a 2 byte pointer be too expensive?
(Pick whatever endian you want for said pointer, of course)

2) Are you sure that a "configuration space" system is the best way to do things? I personally think that a system built upon standard commands would be better - that is, a device might have commands like
  • $00 Configuration Protocol Version
    Returns the version of the configuration protocol supported as a byte. This is to be interpreted with the most significant bit indicating a backwards incompatible change.
  • $01 Reset Device
    Causes the device to do a complete internal reset.
  • $02 Enumerate Function
    Each time invoked, returns another function supported by the device. This starts with the first byte indicating the length of the function description (excluding this first byte), followed by an interface UUID, followed by function-dependent information. If the device has no more functions to enumerate, then the size returned should be zero.
and so on.

A few thoughts
  • How do you handle devices with non-overlapping interface sets? For example, your mentioned keyboard interface which can be in Scancode or Unicode modes.
  • How do you handle devices which change capabilities? This is similar to the above, except rather than the system changing what they do, they for one reason or another need to change their abilities autonomously
  • How do you handle configuration change notifications? This one seems quite tricky with the single interrupt pin


(Quite a bit of this is of interest to me, because I'm working on something called EmBus for low speed devices. It has some nice logistical simplifications - for example, I don't have support for dumb devices, so don't need a separate configuration space, and that it only requires a 4 pin cable [Vdd, SCL, SDA, Vss] - yes, its I²C based)


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Aug 08, 2010 6:57 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
Some of my answers might read curtly; I apologize in advance. I'm typing this fast.

OwenS wrote:
1) Are you sure that a byte pointer is the best way to reference the UUID list? Would making it a 2 byte pointer be too expensive?
(Pick whatever endian you want for said pointer, of course)


You do not know how big the configuration space is at this point in time, so a single byte is all you can depend on.

Quote:
2) Are you sure that a "configuration space" system is the best way to do things?


Right now, in the web application world, RPC is being phased out universally in favor of REST. That is, they're replacing interfaces with a plurality of detailed commands with an interface consisting exclusively of open, read, write, and close. (Well, GET, PUT, POST, and DELETE in the web's case, but you get the idea.) Think of how simple and flexible Commodore's "everything is a GPIB device" or Unix's "everything's a file" metaphor works.

Firewire works similarly, where devices do not expose command-based interfaces like USB does, but rather portions of a 64-bit address space. Peripherals are mapped in this space, just as PCI devices are mapped in the CPU's address space. In fact, most Firewire adapter cards are nothing more than CPU-address-space-to-Firewire-address-space bridges. That way, the only over-the-wire commands that exist are, in effect, read and write byte,word,long, etc.

I want to capitalize on that simplicity and flexibility, without necessitating a centralized standards body to manage open-ended future expansion. Command-based interfaces don't satisfy that requirement.

Quote:
How do you handle devices with non-overlapping interface sets? For example, your mentioned keyboard interface which can be in Scancode or Unicode modes.


I already detailed this, actually, but perhaps it wasn't readily obvious. You set up a UUID parameter block in configuration space (anywhere there exists free RAM), set $38-.. to point to it, then write $82 into the $30 location. Wait for that byte to become $02. If you've ever coded direct disk controller queue access on a Commodore 1541, you'll already be familiar with this basic interface, for it's directly inspired by it.

Quote:
How do you handle devices which change capabilities? This is similar to the above, except rather than the system changing what they do, they for one reason or another need to change their abilities autonomously


I've never met such a device that wasn't hot-swappable. Those devices which are hot-swappable implement this by faking a swap-out and a swap-in.

Since 65SIB isn't hot-swap capable, I don't support this operation overtly. Device interrupts and a request to change modes is the only supported method.

Quote:
How do you handle configuration change notifications? This one seems quite tricky with the single interrupt pin


You don't, because in practice, it never happens. I look to PCI and SCSI, both internal and external, as examples of this. Even USB devices cannot change configurations dynamically without host intervention. Firewire devices can, of course, but they can do whatever the heck they want -- they emulate arbitrary address spaces, after all!

Again, the peripheral will need to interrupt the master and communicate its desires through its defined protocol.

Hope this clears some things up.

Also, this is just a proposal at this point.

When I first wanted a 65xx-based serial interface, I really wanted to replicate the everything-is-a-GPIB-device philosophy. SPI unfortunately doesn't let me do that; its transactions more closely resemble the client/server interactions you find on the web. Hence my decision to adopt a more REST-like approach than stream-based approach.

If you can think of a way to achieve some of the niceties of Commodore's philosophy while concurrently providing support for device and capability identification and selection on an architecture that is heavily master/slave, I'm open to suggestions. :) I'm always in support of simpler techniques which don't straight-jacket me in the future.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Aug 08, 2010 7:05 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
OK, here is my revised idea. See if this makes more sense or seems easier to implement.

Each configurator is responsible for maintaining at least one "resource." For the purposes of communicating with the configurator, a resource is just an opaque blob of bytes. Requests take the following form:

Code:
For GET, PUT, POST, and DELETE requests:

    $00  Request Format Version (must be 0 for now)
    $01  Command Byte (0=GET, 1=PUT, 2=POST, 3=DELETE, 4..255 undefined)
    $02  Resource ID
    $03  unused; for compatibility, set to 0.

For PUT, POST request only:

$04-$05  Length of data which follows
$06-...  Raw data to store.


While transmitting the request, the peripheral must transmit $FF over the MISO line. When the configurator is ready to send back a response, it starts out by transmitting a $00 as the "start byte", followed by a structure not entirely different from that documented above. The only difference is that byte $03 becomes an error indicator:

Code:
For GET, PUT, POST, and DELETE responses:

    $00  Response Format Version (must be 0 for now)
    $01  Command which generated this response (0=GET, 1=PUT, 2=POST, 3=DELETE, 4..255 undefined)
    $02  Resource ID accessed
    $03  Response Code/Error Indication

For GET responses only:

$04-$05  Length of the data which follows
$06-...  Raw data follows.


Some response codes I can think of:
Code:
  Code   Error? Description
---------------------------------------------------------------------
   00      N    Successful; data follows.
   01      N    Successful; but, no content.
   03      N    Not enough data; assuming defaults for missing data.
   04      N    Supported protocol.
   80      Y    Unknown error.
   81      Y    Resource not supported.
   82      Y    Attempt to write to a read-only resource.
   83      Y    Not enough data.
   84      Y    Unsupported protocol.
---------------------------------------------------------------------

etc.

Specific meaning of the bytes transfered depends on which resource is being read from or written to.

Resource 0

This resource is the "index" resource. It exists to identify the device and its timing characteristics. It's read-only.

Code:
    $00  Format Version (currently 0)
    $01  Number of protocols this peripheral supports
    $02  Resource ID listing all supported protocol IDs.
    $03  Protocol select resource ID.
    $04  Resource ID to query protocol compatibility.
    $05  Unused -- reads as zero.  (Padding.)
    $06  Unused -- reads as zero.  (Padding.)
    $07  Unused -- reads as zero.  (Padding.)
$08-$0B  Maximum device bits per second data transfer rate on 65SIB bus.
$0C-$0F  Maximum configuration bits per second data transfer rate on 65SIB bus.
$10-$13  Minimum latency between bus transactions for device.
$14-$17  Maximum latency between bus transactions for device.
$18-$1B  Minimum latency between bus transactions for config.
$1C-$1F  Maximum latency between bus transactions for config.
$20-$23  Model ID (chosen exclusively by the vendor)
$24-$2F  Unused -- reads as zero.  (Padding.)
$30-$3F  Vendor UUID.


Resource A

Byte $02 of resource 0 contains the resource ID of the resource listing all the supported protocols. This resource is also read-only.

The format returned by a GET is just an array of UUIDs.

Resource B

Byte $03 of resource 0 contains the resource ID that you can PUT to to switch operating protocols. If the UUID that is PUT here doesn't appear in the list of supported formats, error $84 must be returned.

A GET returns the current protocol UUID.

Resource C

Sometimes, you don't want to change protocols, but you just want to see if the current operating protocol supports the functionality of another protocol. You can query this by PUT-ing or POST-ing the candidate UUID to this resource, identified by byte $04 in resource 0. The response back will be either $04 if the current operating protocol is compatible, or $84 if not.

Comments?


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Aug 08, 2010 11:20 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
I edited my previous reminder into a more cohesive description of my epiphany.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Aug 09, 2010 12:31 am 
Offline

Joined: Thu Jul 26, 2007 4:46 pm
Posts: 105
That sounds pretty good, though I do have to ask: Do you really need methods other than "GET" and "SET"?


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Aug 09, 2010 1:06 am 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
For what's described, no. GET and PUT would be plenty sufficient. But, having the ability to POST new content might be useful in supporting hardware that can create new configurations on demand; likewise, DELETE for cleaning things up later. It's just a thought.

Generally speaking, for any kind of resource, you should make available some form of CRUD system: Create, Read, Update, Delete. So, I'd like to at least have the commands reserved, even if they're left unused in practice.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Aug 09, 2010 2:53 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8520
Location: Southern California
Just to make double sure, and clarify for everyone else-- what you're proposing here is all with CONF\ being low when SEL\ goes down, then SEL\ going up, right? ie, it won't affect command bytes issued when the device is SELected with CONF\ high.

What does REST stand for?

For the parts I understand (which definitely is not all of it), I can't say I find any problem with the above. You are familiar with many different commercial protocols already, which are always good to learn from. Let me ask about this however:

Quote:
Requires that the master be able to write into configuration space to issue commands to a configurator.


It would seem however that the addresses some of the info is stored at shouldn't matter to the host, and that the list of parameters following a command from the master, or a response sent by the device, should start with a count byte, to avoid getting the protocol painted into a corner which could make it difficult for future things that so far have not been thought up. Then a new gizmo that wants more than X number of bytes isn't cornered by a set-in-stone address map, and something simpler with very limited resources doesn't have to dedicate more space than it needs. Is there some validity to this? Or is that the reason for this:

Quote:
Code:
Accress  Read/Write  Description
    $00     R        Configuration space verions (= 0)



?

Quote:
I've never met such a device that wasn't hot-swappable. Those devices which are hot-swappable implement this by faking a swap-out and a swap-in.

Since 65SIB isn't hot-swap capable, I don't support this operation overtly.

There could be however an SD-card 65SIB device where the SD card itself is hot-swapable, and even though you swap for another SD card (ie, the same kind of thing, not a relay box or something unrelated), the memory size could suddenly change.


Top
 Profile  
Reply with quote  
PostPosted: Tue May 31, 2022 6:55 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
A recent e-mail from Garth has reminded me of this post.

I sure am glad nobody implemented this. 12 years of accumulated experience since this post has left me wondering how economical this approach to a configuration mechanism this approach would have been. My current hunch says not very. So, take it from me, the author of this spec -- DO NOT implement this spec as written. ;)

I like the idea of using UUIDs as interface descriptors and including specs for timing parameters; but, the "treat config space as random-access memory coupled with do-this-here style commands" approach seems unnecessarily complicated to me now. OwenS was right; sticking with a message-passing approach would have worked better.

At the time, in 2010, REST (Representational State Transfer, to answer Garth's question above) was all the rage and it looked very much like everyone was switching to it. While it remains a useful approach for implementing remote services online, since 2010 when I made that post, most people implementing a "REST"-ful service has not fully committed to its ideals; the result is a hodgepodge solution that has some REST-y features and some RPC features mixed in. This suggests my original vision of applying a REST-y approach to configuration space was misguided. RPC is the right way to go.

Also, to answer another question from Garth, the method of accessing configuration space can be described with this timing diagram:
Code:
             ____
CONF\            \____________________________
             ________      ___________________
SEL\                 \____/
             _________________    __    __   
CLK          ____/            \__/  \__/  \__/ ...
             ______________ __ __ __ __ __ __
MISO/MOSI    ______________X__X__X__X__X__X__X ...


However, this was (and still remains) not thought out completely. I will need to deep-dive and perform experiments to see what will and will not work here.


Top
 Profile  
Reply with quote  
 Post subject: Re:
PostPosted: Tue May 31, 2022 7:11 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
GARTHWILSON wrote:
It would seem however that the addresses some of the info is stored at shouldn't matter to the host, and that the list of parameters following a command from the master, or ...


Yup; this whole idea is basically a non-starter.

In 2010, I was probably thinking in terms of how Forth operates on a stack -- you push stuff onto the stack, then give an operation, then read stuff off the stack. Likewise, in this configuration approach, you'd write something into config-space using a generic memory-write operation, you'd pass a simple command to operate on whatever you stuffed into config-space memory, and then you'd read the results back from some buffer.

While this would work, experience both in distributed software and in hardware suggests that this approach either isn't economical or just plain isn't desirable. Pure REST has limited deployment in practice, and FireWire died, leaving both USB and Thunderbolt to replace it, both of which are message-oriented protocols (PCI-e notwithstanding).

GARTHWILSON wrote:
There could be however an SD-card 65SIB device where the SD card itself is hot-swapable, and even though you swap for another SD card (ie, the same kind of thing, not a relay box or something unrelated), the memory size could suddenly change.


Yep, I didn't think that through at the time; however, some time later, I've come to realize there's a clear distinction between the controller and the unit it controls. It only took me six years to learn that lesson, but I did eventually learn it. :)


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 8 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: