Linked by Hadrien Grasland on Fri 30th Dec 2011 08:24 UTC
Hardware, Embedded Systems In the world of alternative OS development, portability across multiple architectures is a challenging goal. Sometimes, it may be intrinsically hard to come up with hardware abstractions that work well everywhere, but many times the core problem is one of missing information. Here, I aim at learning more about the way non-x86 architectures deal with CPU IO ports, and in particular how they prevent user-mode software from accessing them.
Thread beginning with comment 501806
To view parent comment, click here.
To read all comments associated with this story, please click here.
RE: Memory mapped I/O and ports
by Anachronda on Sat 31st Dec 2011 20:58 UTC in reply to "Memory mapped I/O and ports"
Anachronda
Member since:
2007-04-18

This was carried out to the ultimate level with DEC VAX system - the high order 2 bits selected the system level - 00 - user, 01 - supervisor, 10 -interrupt, 11 device (as I recall).

You're actually mixing two different view of the VAX address space.

In a physical address, bit 29 typically selects I/O or memory. Bits 30 and 31 are typically used (at least in the microprocessor implementations) to encode the length of a transaction on the bus.

In a virtual address, bits 30 and 31 select the address space, where 00 is a user space growing up (i.e., code and data), 01 is a user space growing down (i.e., the user stack), 10 I'm fuzzy on, and 11 is system space. I/O typically winds up mapped into system space, although it's possible (with suitable privileges) to map regions of the other address spaces to I/O space.

Reply Parent Score: 1

JPollard Member since:
2011-12-31

Not quite.

00 is user space. But the stack started at 01 and worked down (so the first usable byte is in 00).

DCL, RMS,and such lived in 01.

10 was where the kernel resided.

11 was reserved, but where all the physical devices lived. It mapped entire bus systems (UNIBUS,QBUS, BI...)

The system was mapped this way because that was the only way system calls could be made. The CMx (change mode to Kernel/whatever) instructions would not work in P0 space, system calls were an entry into P1/P2 address pages, and the first instruction was required to be a CMx instruction (then followed by a jump), otherwise an illegal access fault occurred.

As far as I recall (and I don't have my books handy) all physical I/O was defined by the MMU, and as such could use/map any physical bit of the bus for whatever it wanted. The CPU didn't interact with it (other than loading it via OS functions).

It was interesting with the boot code - it always emulated a PDP-11 during initial boot, with the default peripherals always mapped to 017xxxx (octal) address range. Didn't matter which bus was mapped (QBus/UNIBUS or the BI), that was where the peripherals were mapped by default. Once SYSBOOT was loaded, it (meaning the loaded boot program) would switch to native mode and initialize all the hardware and load the kernel.

Granted, I only worked on one VAX driver (a printer/plotter), but it's device address as used by the driver was starting with a 11 bit pattern.

Reply Parent Score: 1

Anachronda Member since:
2007-04-18

Not quite. 00 is user space. But the stack started at 01 and worked down (so the first usable byte is in 00). DCL, RMS,and such lived in 01. 10 was where the kernel resided. 11 was reserved, but where all the physical devices lived.

Yeah, I knew I had botched 10 and 11 just after I posted it.

It mapped entire bus systems (UNIBUS,QBUS, BI...) The system was mapped this way because that was the only way system calls could be made. The CMx (change mode to Kernel/whatever) instructions would not work in P0 space, system calls were an entry into P1/P2 address pages, and the first instruction was required to be a CMx instruction (then followed by a jump), otherwise an illegal access fault occurred.

Hmm. I don't see those restrictions on the CHMx instructions in the VAX Architecture Reference Manual. The only restrictions I see are that CHMx cannot be executed while running on the interrupt stack and the new mode has to have enough privilege to access the old mode's stack.

It was interesting with the boot code - it always emulated a PDP-11 during initial boot, with the default peripherals always mapped to 017xxxx (octal) address range. Didn't matter which bus was mapped (QBus/UNIBUS or the BI), that was where the peripherals were mapped by default. Once SYSBOOT was loaded, it (meaning the loaded boot program) would switch to native mode and initialize all the hardware and load the kernel.

I'm curious about which machine you worked with. The big machines tended to have a captive PDP-11 (LSI-11 in the case of the /780, various Pro models in 8xxx machines). As I understand it, the PDP-11 was responsible for loading the microcode into the processor and the bootstrap into memory, then lighting off the VAX.

QBus machines tended to be built with processors that didn't support compatibility mode. At reset, they'd start running VAX code from ROM, which would go fetch the bootstrap.

I'm not sure how the /730 and /750 booted.

Reply Parent Score: 1