Last visit was: Sun Sep 19, 2021 10:34 am
It is currently Sun Sep 19, 2021 10:34 am



 [ 3 posts ] 
 passing address parameters in a segmented architecture 
Author Message

Joined: Sat Feb 02, 2013 9:40 am
Posts: 1484
Location: Canada
What is the best means of passing address pointers in a segmented architecture ?

Background:

I have a really simple segmented processor core in the works.
Its a 32 bit word oriented RISC processor (30-40 insn). Using segments a 40 bit address is supported (2^42 bytes).
The goal is having enough support to run an OS like LINUX.
The core is not pipelined. It takes multiple clock cycles to fetch, decode and execute each instruction. A typical instruction will take five clock cycles.
The segmentation model allows virtual addresses with bounds checking. There's no stack segment.
Stack addresses are part of the data segment, but there are dedicated stack upper and lower bounds registers, and a stack fault rather than a bounds fault. There's minimal privilege level checking on some instructions that should be executed only in supervisor mode.
There are four complete sets of registers including segment registers and the flags register. There is one set for each operating mode. So there is no need to save/restore registers when switching modes.
The upper three bits of an effective address identify the segment register used for address formation. So addressing is limited to 29 bits (2GB) in a segment. The program counter is limited to 27 bits (512MB per segment) this is tied to the fact there is only 27 bits available in an jump instruction to specify the address with.

I came up with a way to pass address parameters by first disecting the address into components using extraction instructions. But it's really ugly but I can't see an easy way around it. The actual values for the segmented part of the address have to be passed as well as the offset. So ther's an extraction at call time and then a rebuild of the address inside the API function.
Code:
   
// Before the call to the api
// For instance the pointer might be to thread data in fs:r1
    exs   r2,r1             ; extract segment value into r2
    exl   r3,r1             ; extract segment limit value
    and   r1,r1,#$1FFFFFFF  ; clear the top 3 bits of offset
    mov   sys,r1,r2,r3      ; move registers to system regs
    brk   #1                ; invoke the api

// Sample entrance to api, perhaps to display a string
// The register set is automatically switched by the BRK
// instruction. The move to alternate register set
// instruction must have been used to setup parameters.
//
api_entrance:
    mtspr es,r2           ; use es as the segment register
    mtspr esl,r3          ; and set limit
    or    r1,r1,#$20000000   ; set reference to es
    ; the pointer is now in es:r1
    ...
    rti

The BRK instruction stores the code segment limit, code segment,program counter and machine status word on the stack. And switches to register set #2.
The RTI instruction then restores them all. And switches back to the original register set.

_________________
Robert Finch http://www.finitron.ca


Mon Aug 22, 2016 11:05 am WWW

Joined: Wed Jan 09, 2013 6:54 pm
Posts: 1632
(Just a quick thought: if you constrain passed addresses to be aligned on a suitable (paragraph) boundary then you can pass the high order bits and the low order ones can be taken to be zero.)


Mon Aug 22, 2016 5:15 pm

Joined: Sat Feb 02, 2013 9:40 am
Posts: 1484
Location: Canada
I'd really like to move the segment extraction code into the called API so that the user program doesn't have to worry about it. The user program shouldn't have to know about segments. It can be done but its a number of lines of code. I figure there's got to be a better way. I could modify the segment extract instructions to accept the register set as another parameter to the instruction, but those instructions are already ugly. They'd be very specific purpose instructions. It's possible to get at the segment registers without the extract instructions but it's another 20 lines of code. Calling an API shouldn't cause 50 lines of code to be executed just to get at a parameter. What if there's two or three addresses passed ?

Code:
// Before the call to the api
// For instance the pointer might be to thread data in fs:r1
    mov   sys,r1,r2,r3      ; move registers to system regs
    brk   #1                ; invoke the api

api_entrance:
    ; First switch registers to the user register set so that
    ; the segment and limit can be extracted, then switch back
    ; to the system register set.
    ld    r10,mswx[sp]    ; get user machine status word from stack
    shr   r10,r10,#8      ; extract the register set field - bits 8,9
    and   r10,r10,#3      ; r10 = register set
    mfspr r11,msw         ; get running machine status word
    and   r11,r11,#$FFFFFCFF  ; clear register set bits
    shl   r10,r10,#8      ; shift bits into position
    or    r11,r11,r10     ; set the bifield
    mtspr msw,r11         ; switch to user register set
    ; r29,r30 are user mode registers !
    ; they must be reserved for use by the system
    exs   r29,r1          ; get the segment
    exl   r30,r1          ; and segment limit
    mov   sys,r29,r30     ; move to system registers
    mfspr r29,msw         ; r29 = machine status word
    and   r29,r29,#$FFFFFCFF  ; clear register set bits
    or    r29,r29,#$00000200  ; set system mode registers
    mtspr msw,r29         ; r29 is user mode here
    mtspr es,r29          ; and system mode here
    mtspr esl,r30
    or    r1,r1,#$2000000
    ; the pointer is now in es:r1
    ... ; continue with api code
    rti

_________________
Robert Finch http://www.finitron.ca


Mon Aug 22, 2016 8:27 pm WWW
 [ 3 posts ] 

Who is online

Users browsing this forum: CCBot and 0 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

Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software