-
Notifications
You must be signed in to change notification settings - Fork 133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add slice
and slice_mut
methods to IDT
#95
Conversation
Thanks for the pull request! We used to have this field public, but it caused lots of confusion because it starts at index 32 of the IDT. So if you wanted to set a handler for the 34th entry in the IDT, you would need to access How about a different solution: The The implementation would be similar to the existing |
Sounds like a good idea. I had considered something similar before. I'll update the request when I've got something unless you want to close this one and have me submit another. |
Great, thanks a lot! I'm fine with keeping this PR open if you like. |
I changed the index trait to operate on RangeBounds, but there's a consequence that I wasn't sure how to avoid without putting everything into an array. The existing named exception handlers cannot be returned since the index return type changed from &Entry to &[Entry]. One solution is to put each handler in an array of size 1. Not sure it is preferrable. I'm not sure what the impact to others would be by removing access to the exception handlers via the Index trait. |
We could use the |
src/structures/idt.rs
Outdated
let lower_idx = match index.start_bound() { | ||
Included(start) => *start, | ||
Excluded(start) => *start + 1, | ||
Unbounded => 32, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer to error in this case because it would be confusing that ..256
is a smaller range than 0..256
.
I initially looked at SliceIndex and didn't implement since I didn't seem to have direct access to the range values passed. The only possible option I see is to use some pointer math to compute the index desired. The other option is to implement a custom generic trait similar to SliceIndex which provides a templated return type and index type, but which allows access to the index range. Do you have any thoughts as to which is more desirable (or another idea entirely)? OT: I'm using a bit of mix between your first and second edition of your "Writing an OS in Rust" blogs. I'm very much enjoying the challenge and am happy to be able to contribute back in any way. I'm a seasoned C/C++ developer, but still in the learning phase with Rust. |
I've tried everything I can think of to make this work, but I cannot find a way to make it work with the current feature set in Rust. Particularly the lack of trait overloading. I think the best solution I can come up with is to leave the Index trait as it was (don't make breaking changes) and add a slice() method to retrieve a slice. Any index outside of 32..=255 will cause an error. |
Ah, I see. I can't think of a good solution either…
Sounds good to me! It's still straightforward to use without breaking any existing code or introducing a complicated custom trait.
Great to hear that you like it! And thanks again for submitting this pull request. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a few inline comments, but otherwise this looks good to me.
src/structures/idt.rs
Outdated
let lower_idx = match bounds.start_bound() { | ||
Included(start) => *start, | ||
Excluded(start) => *start + 1, | ||
Unbounded => 32, | ||
}; | ||
let upper_idx = match bounds.end_bound() { | ||
Included(end) => *end + 1, | ||
Excluded(end) => *end, | ||
Unbounded => 255, | ||
}; | ||
|
||
if lower_idx > 255 || upper_idx > 255 { | ||
panic!("Index out of range [{}..{}]", lower_idx, upper_idx); | ||
} | ||
if lower_idx < 32 { | ||
panic!("Cannot return slice from traps, faults, and exception handlers"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can factor out the index checks and adjustments into a separate private method to avoid the duplication for slice
and slice_mut
.
src/structures/idt.rs
Outdated
let lower_idx = match bounds.start_bound() { | ||
Included(start) => *start, | ||
Excluded(start) => *start + 1, | ||
Unbounded => 32, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unbounded should be equivalent to 0
for an usize
range so that 0..100
and ..100
have the same effect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doh, I had this right, then ended up copying the mistake back in during my multiple refactors.
src/structures/idt.rs
Outdated
Unbounded => 255, | ||
}; | ||
|
||
if lower_idx > 255 || upper_idx > 255 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be 256
since the upper bound is excluded so that 32..256
is a valid range?
slice
and slice_mut
methods to IDT
Thanks a lot! Just for your information: I updated the pull request title and description to reflect the latest version of the PR. |
Published as version v0.7.7. |
The current IDT structure doesn't provide much in the way of dynamic management. I would like to be able to manage hardware interrupts externally. By
making idt.interrupts publicaddingslice
andslice_mut
methods, I can return a slice of interrupt vectors to a hardware interrupt controller class so that that class can assign it's own handlers in the IDT. Without this, the external class needs direct access to the IDT.