what does this code mean in xv6 entrypgdir? - xv6

I'm currently delving into the xv6 operating system. I have a question for the below code snippet. I know entrypgdir is an array of pde_t type with size of NPDENTRIES. But what does "[0] = (0) | PTE_P | PTE_W | PTE_PS" mean?
Thanks in advance
__attribute__((__aligned__(PGSIZE)))
pde_t entrypgdir[NPDENTRIES] = {
// Map VA's [0, 4MB) to PA's [0, 4MB)
[0] = (0) | PTE_P | PTE_W | PTE_PS,
// Map VA's [KERNBASE, KERNBASE+4MB) to PA's [0, 4MB)
[KERNBASE>>PDXSHIFT] = (0) | PTE_P | PTE_W | PTE_PS,
};

The code is initializing the contents of the page directory. (See designated array initialization in C).
Consider this image of the contents of a page directory entry from OSDev Wiki:
Then consider this line of code:
[0] = (0) | PTE_P | PTE_W | PTE_PS
The code sets the value of the first page directory entry (index 0) to 0 | PTE_P | PTE_W | PTE_PS. This is a bitwise OR to set the various fields:
0 - clear all bits
PTE_P - set the present bit
PTE_W - set the read\write bit
PTE_PS - set the 4MiB page size bit
The next line does a similar thing. Except it sets the contents of the 513th entry (index 512 (0x80000000 >> 22)):
[KERNBASE >> PDXSHIFT] = (0) | PTE_P | PTE_W | PTE_PS
.
Aside:
The bit position of the flags of interest to xv6 is the same for page directory entries (PDE) and page table entries (PTE). Instead of creating separate constants for the PDE flags, the authors opted to share the constants... In my opinion, this shortcut makes the code slightly less clear in intent.
// Page table/directory entry flags.
#define PTE_P 0x001 // Present
#define PTE_W 0x002 // Writeable
#define PTE_U 0x004 // User
#define PTE_PS 0x080 // Page Size

Related

Rust - Collecting slices of a Vec in a recursive function

I am currently trying to build a huffman encoding program and am struggling with a problem I have while traversing my generated huffman tree to create a lookup table. I decided to implement said traversal with a recursive function. In the actual implementation I use the bitvec crate to save bitsequences, but for simplicitly I will use Vec<bool> in this post.
The idea I had was to save a collection of all codewords in the Vec codewords and then only save a slice out of that vector for the actual lookup table, for which I used a HashMap.
The issue is how exactly I would solve adding a 0 or a 1 for both the left and right traversal. My idea here was to save a clone of a slice of the current sequence, append a 0 to codewords, then append that clone to the end of codewords after traversing to the left so that I can push a 1 and traverse to the right. The function I came up with looks like this:
use std::collections::HashMap;
// ignore everything being public, I use getters in the real code
pub struct HufTreeNode {
pub val: u8,
pub freq: usize,
pub left: i16,
pub right: i16,
}
fn traverse_tree<'a>(
cur_index: usize,
height: i16,
codewords: &'a mut Vec<bool>,
lookup_table: &mut HashMap<u8, &'a [bool]>,
huffman_tree: &[HufTreeNode],
) {
let cur_node = &huffman_tree[cur_index];
// if the left child is -1, we reached a leaf
if cur_node.left == -1 {
// the last `height` bits in codewords
let cur_sequence = &codewords[(codewords.len() - 1 - height as usize)..];
lookup_table.insert(cur_node.val, cur_sequence);
return;
}
// save the current sequence so we can traverse to the right afterwards
let mut cur_sequence = codewords[(codewords.len() - 1 - height as usize)..].to_vec();
codewords.push(false);
traverse_tree(
cur_node.left as usize,
height + 1,
codewords, // mutable borrow - argument requires that `*codewords` is borrowed for `'a`
lookup_table,
huffman_tree,
);
// append the previously saved current sequence
codewords.append(&mut cur_sequence); // second mutable borrow occurs here
codewords.push(true); // third mutable borrow occurs here
traverse_tree(
cur_node.right as usize,
height + 1,
codewords, // fourth mutable borrow occurs here
lookup_table,
huffman_tree,
);
}
fn main() {
// ...
}
Apparently there is an issue with lifetimes and borrowing in that snippet of code, and I kind of get what the problem is. From what I understand, when I give codewords as a parameter in the recursive call, it has to borrow the vector for as long as I save the slice in lookup_table which is obviously not possible, causing the error. How do I solve this?
This is what cargo check gives me:
error[E0499]: cannot borrow `*codewords` as mutable more than once at a time
--> untitled.rs:43:5
|
14 | fn traverse_tree<'a>(
| -- lifetime `'a` defined here
...
34 | / traverse_tree(
35 | | cur_node.left as usize,
36 | | height + 1,
37 | | codewords, // mutable borrow - argument requires that `*codewords` is borrowed for `'a`
| | --------- first mutable borrow occurs here
38 | | lookup_table,
39 | | huffman_tree,
40 | | );
| |_____- argument requires that `*codewords` is borrowed for `'a`
...
43 | codewords.append(&mut cur_sequence); // second mutable borrow occurs here
| ^^^^^^^^^ second mutable borrow occurs here
error[E0499]: cannot borrow `*codewords` as mutable more than once at a time
--> untitled.rs:44:5
|
14 | fn traverse_tree<'a>(
| -- lifetime `'a` defined here
...
34 | / traverse_tree(
35 | | cur_node.left as usize,
36 | | height + 1,
37 | | codewords, // mutable borrow - argument requires that `*codewords` is borrowed for `'a`
| | --------- first mutable borrow occurs here
38 | | lookup_table,
39 | | huffman_tree,
40 | | );
| |_____- argument requires that `*codewords` is borrowed for `'a`
...
44 | codewords.push(true); // third mutable borrow occurs here
| ^^^^^^^^^ second mutable borrow occurs here
error[E0499]: cannot borrow `*codewords` as mutable more than once at a time
--> untitled.rs:48:9
|
14 | fn traverse_tree<'a>(
| -- lifetime `'a` defined here
...
34 | / traverse_tree(
35 | | cur_node.left as usize,
36 | | height + 1,
37 | | codewords, // mutable borrow - argument requires that `*codewords` is borrowed for `'a`
| | --------- first mutable borrow occurs here
38 | | lookup_table,
39 | | huffman_tree,
40 | | );
| |_____- argument requires that `*codewords` is borrowed for `'a`
...
48 | codewords, // fourth mutable borrow occurs here
| ^^^^^^^^^ second mutable borrow occurs here
What am I missing here? Is there some magical function in the vector API that I'm missing, and why exactly does this create lifetime issues in the first place? From what I can tell, all my lifetimes are correct because codewords always lives for long enough for lookup_table to save all those slices and I never mutably borrow something twice at the same time. If there was something wrong with my lifetimes, the compiler would complain inside the if cur_node.left == -1 block, and the cur_sequence I take after it is an owned Vec, so there can't be any borrowing issues with that. So the issue really is with the core idea of having a recursive function with a mutable reference as a parameter.
Is there any way for me to solve this? I tried making codewords owned and returning it, but then the compiler cannot ensure that the bitsequence I'm saving inside lookup_table lives for long enough. The only idea I still have is to save owned vectors inside lookup_table, but at that point the codewords vector is obselete in the first place and I can simply implement this by having a cur_sequence vector as parameter which I clone in every call, but I chose my approach for a better cache performance in the actual encoding process right after, which I would then lose.
The problem is that when you create a slice cur_sequence from codewords like you did in let cur_sequence = &codewords[(codewords.len() - 1 - height as usize)..];, the compiler extends the lifetime of the reference to codewords to at least the same as cur_sequence (why: The compiler wants to ensure that the slice cur_sequence is always valid, but if you change codewords (say, clear it) then it's possible that cur_sequence is invalid. By keeping an immutable reference to codewords, then borrow rules will forbid modification of codewords when the slice is still alive). And unfortunately you save cur_sequence in lookup_table, thus keeping the reference to codewords alive all over the function, so you cannot mutably borrow codewords anymore.
The solution is to maintain the indexes of the slice by yourself: create a struct:
struct Range {
start: usize,
end: usize
}
impl Range {
fn new(start: usize, end: usize) -> Self {
Range{ start, end}
}
}
then use it instead of the slices:
let cur_range = Range::new(
codewords.len() - 1 - height as usize,
codewords.len() - 1
);
lookup_table.insert(cur_node.val, cur_range);
In this way, the responsibility to keep the ranges valid is yours.
complete code:
use std::collections::HashMap;
// ignore everything being public, I use getters in the real code
pub struct HufTreeNode {
pub val: u8,
pub freq: usize,
pub left: i16,
pub right: i16,
}
struct Range {
start: usize,
end: usize
}
impl Range {
fn new(start: usize, end: usize) -> Self {
Range{ start, end}
}
}
fn traverse_tree(
cur_index: usize,
height: i16,
codewords: &mut Vec<bool>,
lookup_table: &mut HashMap<u8, Range>,
huffman_tree: &[HufTreeNode],
) {
let cur_node = &huffman_tree[cur_index];
// if the left child is -1, we reached a leaf
if cur_node.left == -1 {
// the last `height` bits in codewords
// let cur_sequence = &codewords[(codewords.len() - 1 - height as usize)..];
let cur_range = Range::new(
codewords.len() - 1 - height as usize,
codewords.len() - 1
);
lookup_table.insert(cur_node.val, cur_range);
return;
}
// save the current sequence so we can traverse to the right afterwards
let mut cur_sequence = codewords[(codewords.len() - 1 - height as usize)..].to_vec();
codewords.push(false);
traverse_tree(
cur_node.left as usize,
height + 1,
codewords, // mutable borrow - argument requires that `*codewords` is borrowed for `'a`
lookup_table,
huffman_tree,
);
// append the previously saved current sequence
codewords.append(&mut cur_sequence); // second mutable borrow occurs here
codewords.push(true); // third mutable borrow occurs here
traverse_tree(
cur_node.right as usize,
height + 1,
codewords, // fourth mutable borrow occurs here
lookup_table,
huffman_tree,
);
}
fn main() {
// ...
}

Why the keyboard input is written back to IO bus in xv6?

I do not understand why the input got from keyboard interrupt is written back to the io bus again:
This is the keyboard interrupt handler:
void consoleintr(int (*getc)(void)) {
// I skipped some code for simplicity
default:
if(c != 0 && input.e-input.r < INPUT_BUF){
c = (c == '\r') ? '\n' : c;
input.buf[input.e++ % INPUT_BUF] = c;
-----> consputc(c);
if(c == '\n' || c == C('D') || input.e == input.r+INPUT_BUF){
input.w = input.e;
wakeup(&input.r);
}
}
break;
}
}
The input c is taken from getc function and written to input.buf ring buffer and right after that it is passed to consputc function.
consputc function calls uartputc which calls outb(COM1+0, c).
The uartgetc function also registered as a input for consoleintr function:
static int uartgetc(void) {
if (!uart) {
return -1;
}
if (!(inb(COM1 + 5) & 0x01)) {
return -1;
}
return inb(COM1+0);
}
void uartintr(void) {
consoleintr(uartgetc);
}
Links to the code:
consoleintr: https://github.com/mit-pdos/xv6-public/blob/master/console.c#L192
consputc: https://github.com/mit-pdos/xv6-public/blob/master/console.c#L166
uartputc: https://github.com/mit-pdos/xv6-public/blob/master/uart.c#L52
The key pressed from keyboard is not resent to be processed again, but is send to output:
The uart is some kind of serial line, it is used in two ways: input and output.
The keyboard in only an input device.
When you press a key, the key pressed will be sent to serial out.
A small schematics may explain better:
+-------------+
| | +--------------+
| Keyboard +-----+ +---->+ Screen (term)|
| | | | +--------------+
+-------------+ | +------------+ |
| | | | +----------------+
+--->| Char to +-----+----->+ Input (process)|----> ....
| | process | | +----------------+
+--------------+ | +------------+ | +--------------+
| | | +---->+ Serial: out |
| Serial: in +----+ | outb(...) |
| inb(...) | +--------------+
+--------------+

Render widgets to different positions on paintdevice

With Qt I want to print multiple widgets onto a single DINA4-page.
Say I have 3 widgets that I want to place directly next to each other:
-------
| A |
-------
| B |
-------
| C |
-------
As I render them in my code below, all 3 widgets are rendered above each other at the postion of C (or even A and B are not rendered at all, I don't see it). I intended to move each widget a little bit down by the size of the last widget, to render it directly next to the last one. This seems not to work:
int lastWidgetHeight;
lastWidgetHeight= 0;
for (int i = 0; i < this->widgets.size(); i++){
Wid* e = widgets.at(i);
QWidget *printBox = e->printArea();
// define float scaleX and scaleY [...]
QPainter painter;
painter.begin(printer);
painter.scale(scaleX,scaleY);
// render and translate in y-direction:
printBox->render(&painter, QPoint(0,lastWidgetHeight)); // <-- My idea
painter.end();
lastWidgetHeight+= e->height();
}
If all 3 widgets are rendered, then how does the loop affect the position of A and B, since I create a new QPainter-Object each time?
You can set your 3 elements in a layout
QVVoxLayout *Vertical_layout;
this->getLayout()->addLayout(this->Vertical_layout);
Vertical_layout->addItem(ElementA);
Vertical_layout->addItem(ElementB);
Vertical_layout->addItem(ElementC);
and you can set the distance between them with:
Vertical_layout- >setContentsMargins(left,top,right,bottom);
With that they will always be in their place.

MSP430 Real time clock (RTC_B) doesn't work. Cannot write date/time registers

I'm trying to set date/time registers using the RTC_B module of MSP430F5338 microcontroller.
I'm doing it like this:
RTCCTL0 = 0;
RTCCTL1 |= RTCHOLD +RTCBCD;
RTCHOUR = 0x14;
RTCCTL1 &= ~RTCHOLD;
It doesn't work, and simply ignore the assignements. I cannot understand why. The only strange thing I've noticed is the RTCOFIFG flag set.
Any idea?
Addendum
This is how I set up clock sources:
void clk_init(){
SetVcoreUp (0x01);
SetVcoreUp (0x02);
SetVcoreUp (0x03);
UCSCTL3 = SELREF_2; // Set DCO FLL reference = REFO
UCSCTL4 |= SELA_2; // Set ACLK = REFO
__bis_SR_register(SCG0); // Disable the FLL control loop
UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx
UCSCTL1 = DCORSEL_7; // Select DCO range 50MHz operation
UCSCTL2 = FLLD_1 | ((f_SMCLK/f_ACLK) -1); // Set DCO Multiplier for 25MHz
// (N + 1) * FLLRef = Fdco
// (762 + 1) * 32768 = 25MHz
// Set FLL Div = fDCOCLK/2
__bic_SR_register(SCG0); // Enable the FLL control loop
// Loop until XT1,XT2 & DCO stabilizes - In this case only DCO has to stabilize
do{
UCSCTL7 &= ~(XT2OFFG | XT1LFOFFG | DCOFFG);
// Clear XT2,XT1,DCO fault flags
SFRIFG1 &= ~OFIFG; // Clear fault flags
}while (SFRIFG1&OFIFG); // Test oscillator fault flag
}
void SetVcoreUp (unsigned int level)
{
// Open PMM registers for write
PMMCTL0_H = PMMPW_H;
// Set SVS/SVM high side new level
SVSMHCTL = SVSHE | SVSHRVL0 * level | SVMHE | SVSMHRRL0 * level;
// Set SVM low side to new level
SVSMLCTL = SVSLE | SVMLE | SVSMLRRL0 * level;
// Wait till SVM is settled
while ((PMMIFG & SVSMLDLYIFG) == 0);
// Clear already set flags
PMMIFG &= ~(SVMLVLRIFG | SVMLIFG);
// Set VCore to new level
PMMCTL0_L = PMMCOREV0 * level;
// Wait till new level reached
if ((PMMIFG & SVMLIFG))
while ((PMMIFG & SVMLVLRIFG) == 0);
// Set SVS/SVM low side to new level
SVSMLCTL = SVSLE | SVSLRVL0 * level | SVMLE | SVSMLRRL0 * level;
// Lock PMM registers for write access
PMMCTL0_H = 0x00;
}
I've SOLVED adding this before clock setup:
while (BAKCTL & LOCKBAK) BAKCTL &= ~LOCKBAK;
Basically this is due to the fact that msp430f5338 has the battery backup system, so you'll need this code before you set XT1 drive ACLK.
Hope this helps.
Having just had a browse through the datasheet - two things:
By setting the RTCBCD flag in RTCCTL1, you're saying you want to use binary-coded decimal, so setting RTCHOUR as 0x0A is nonsense. To write proper BCD for, say, 14:47 (2:47pm), you write the hours as 0x14 and 0x47 as the minutes, i.e., write as you see.
Ensure you're not in low power mode 5 (LPM5) - configuration settings are not retained.
Addendum:
Also, the RTCOFIFG flags says you had a fault with your oscillator, so confirm your circuitry too.

Recursively reverse a linkedlist (code in Stanford CSed library) explanation

My recursion skill is pretty rusty. I've been thinking about this problem and searched the forum for a long time but still cannot understand. Right now I'm looking at the recursively reverse a linked list code from Stanford CS ed library.
#include <stdio.h>
struct Node {
int x;
struct Node *next;
};
void Reverse(struct Node ** headRef){
struct Node* first;
struct Node* rest;
if(*headRef==NULL)
return;
first= *headRef;
rest= first->next;
if(rest==NULL)
return;
Reverse(&rest);
printf("Rest%d\n", (rest)->x); // I added this line to print rest
first->next->next=first;
first->next=NULL;
*headRef=rest;
}
void printList(struct Node* head){
if(!head)
return;
else{
printf("%d ", head->x);
printList(head->next);
}
}
void main(){
struct Node *head;
struct Node * node1= (struct Node*) malloc(sizeof(struct Node));
struct Node * node2= (struct Node*) malloc(sizeof(struct Node));
struct Node * node3= (struct Node*) malloc(sizeof(struct Node));
struct Node * node4= (struct Node*) malloc(sizeof(struct Node));
head= node1;
node1->next=node2;
node1->x=1;
node2->x=2;
node3->x=3;
node4->x=4;
node2->next=node3;
node3->next=node4;
node4->next=NULL;
Reverse(&head);
}
Now suppose I have a linked list 1->2->3->4. What I cannot understand is the last line, which will set the headRef to 4 eventually, I think it should set the headRef to 2. I tried to execute the function and it printed out:
4
4
4
for the variable rest.
However, if I commented the last line in the the Reverse function out, it still reversed the list but would print
4
3
2.
The second result I can understand, but the first one seemed quite confusing. Does the statement "*headRef=rest" do any thing to the variable rest? What does it keep pointing to 4?
Also, if I pass *headRef instead of **headRef (last line is not commented out), it would print the result
4
3
2
too.
Could anyone please explain to me what happened in the memory? Thanks a million.
Before the recursive call to Reverse we have:
first---|
|
v
1->2->3->4->NULL
^
|
|
rest------
After the recursive call to Reverse we have:
first---|
|
v
1->2<-3<-4
| ^
v |
NULL |
rest------------
Now we need to fix 2->NULL to 2->1 by first->next->next=first.
first---|
|
v
1<-2<-3<-4
| ^ ^
|--| |
|
rest------------
Now we need to fix 1->2 to 1->NULL by first->next=NULL.
first---|
|
v
NULL<-1<-2<-3<-4
^
|
|
rest------------
Finally *headRef=rest so that *headRef will point to 4 instead of to 1.
What happens here is as because the recursive call passes the address of rest to the local variable headRef, when each recursive call returns, the statement *headRef=rest already changes the address of rest pointer for the statements coming next in the execution flow.
For the linked list 1->2->3->4 :
Let us assume 1 is stored in address 100, 2 in address 200, 3 in address 300 and 4 in address 400.
PART 1:
the call Reverse(&rest) [rest points to address 400]
first = 400
rest = NULL
as rest is NULL the execution returns to the point after Reverse(400) call
PART 2:
Here first = 300 and rest = 400
after execution of first->next->next=first and first->next=NULL
we have *headRef=rest [rest points to 400]
but this headRef was passed an address of rest=300. So now already for the next step in execution,
rest points to 400.
PART 3:
Now execution returns to the point after Reverse(300) call
But during forward call [first was 200 and rest was 300] and during return [rest = 400]. HERE'S THE TRICK!!!
after execution of first->next->next=first and first->next=NULL
we have *headRef=rest [rest points to 400]
but this headRef was passed an address of rest=200. So now already for the next step in execution,
rest points to 400.
PART 4:
Now execution returns to the point after Reverse(200) call
But during forward call [first was 100 and rest was 200] and during return [rest = 400].
after execution of first->next->next=first and first->next=NULL
we have *headRef=rest [rest points to 400]
and as because this is the initial call, the function returns with *headRef having 400 value.
JOB DONE!

Resources