Compare commits
6 Commits
93d1299bd9
...
b51d5966d4
Author | SHA1 | Date |
---|---|---|
|
b51d5966d4 | |
|
b677633248 | |
|
f2c2cff98a | |
|
fff3d8927c | |
|
0dfa6008ec | |
|
5a20c23569 |
|
@ -0,0 +1,15 @@
|
||||||
|
megs: 1024
|
||||||
|
ata0-master: type=disk, path=builddbg/disk.img, mode=flat, cylinders=512, heads=16, spt=50
|
||||||
|
display_library: sdl2, options="gui_debug"
|
||||||
|
boot: disk
|
||||||
|
com1: enabled=1, mode=file, dev=serial.out, baud=9600, parity=none, bits=8, stopbits=1
|
||||||
|
cpu: model=corei7_sandy_bridge_2600k
|
||||||
|
pci: enabled=1, chipset=i440bx
|
||||||
|
log: bochs.log
|
||||||
|
# TODO: Make this portable, by building bochs locally.
|
||||||
|
romimage: file=/home/drew/opt/bochs/share/bochs/BIOS-bochs-latest
|
||||||
|
vgaromimage: file=/home/drew/opt/bochs/share/bochs/VGABIOS-lgpl-latest.bin
|
||||||
|
vga: extension=vbe
|
||||||
|
port_e9_hack: enabled=1
|
||||||
|
# Breaks on XCHGW %BX, %BX
|
||||||
|
magic_break: enabled=1
|
|
@ -4,6 +4,9 @@ __pycache__/
|
||||||
.ccls-cache/
|
.ccls-cache/
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
|
|
||||||
|
bochs.log
|
||||||
|
serial.out
|
||||||
|
|
||||||
sysroot/bin
|
sysroot/bin
|
||||||
sysroot/usr
|
sysroot/usr
|
||||||
sysroot/.crates.toml
|
sysroot/.crates.toml
|
||||||
|
|
|
@ -15,4 +15,11 @@ fn main() {
|
||||||
curr_directory.to_str().unwrap()
|
curr_directory.to_str().unwrap()
|
||||||
);
|
);
|
||||||
println!("cargo:rustc-link-lib=zion_stub");
|
println!("cargo:rustc-link-lib=zion_stub");
|
||||||
|
|
||||||
|
// Trying to recreate bindings?
|
||||||
|
// Run the following commands
|
||||||
|
// gcc -E zion/include/zcall.h > /tmp/expanded.h
|
||||||
|
// bindgen --verbose --use-core --no-layout-tests /tmp/expanded.h -o rust/lib/mammoth/src/bindings.rs -- -x c++
|
||||||
|
//
|
||||||
|
// Then go fix the ThreadExit struct.
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,153 +1,5 @@
|
||||||
/* automatically generated by rust-bindgen 0.69.4 */
|
/* automatically generated by rust-bindgen 0.69.4 */
|
||||||
|
|
||||||
pub const _STDINT_H: u32 = 1;
|
|
||||||
pub const _FEATURES_H: u32 = 1;
|
|
||||||
pub const _ISOC95_SOURCE: u32 = 1;
|
|
||||||
pub const _ISOC99_SOURCE: u32 = 1;
|
|
||||||
pub const _ISOC11_SOURCE: u32 = 1;
|
|
||||||
pub const _ISOC2X_SOURCE: u32 = 1;
|
|
||||||
pub const _POSIX_SOURCE: u32 = 1;
|
|
||||||
pub const _POSIX_C_SOURCE: u32 = 200809;
|
|
||||||
pub const _XOPEN_SOURCE: u32 = 700;
|
|
||||||
pub const _XOPEN_SOURCE_EXTENDED: u32 = 1;
|
|
||||||
pub const _LARGEFILE64_SOURCE: u32 = 1;
|
|
||||||
pub const _DEFAULT_SOURCE: u32 = 1;
|
|
||||||
pub const _ATFILE_SOURCE: u32 = 1;
|
|
||||||
pub const _DYNAMIC_STACK_SIZE_SOURCE: u32 = 1;
|
|
||||||
pub const __GLIBC_USE_ISOC2X: u32 = 1;
|
|
||||||
pub const __USE_ISOC11: u32 = 1;
|
|
||||||
pub const __USE_ISOC99: u32 = 1;
|
|
||||||
pub const __USE_ISOC95: u32 = 1;
|
|
||||||
pub const __USE_ISOCXX11: u32 = 1;
|
|
||||||
pub const __USE_POSIX: u32 = 1;
|
|
||||||
pub const __USE_POSIX2: u32 = 1;
|
|
||||||
pub const __USE_POSIX199309: u32 = 1;
|
|
||||||
pub const __USE_POSIX199506: u32 = 1;
|
|
||||||
pub const __USE_XOPEN2K: u32 = 1;
|
|
||||||
pub const __USE_XOPEN2K8: u32 = 1;
|
|
||||||
pub const __USE_XOPEN: u32 = 1;
|
|
||||||
pub const __USE_XOPEN_EXTENDED: u32 = 1;
|
|
||||||
pub const __USE_UNIX98: u32 = 1;
|
|
||||||
pub const _LARGEFILE_SOURCE: u32 = 1;
|
|
||||||
pub const __USE_XOPEN2K8XSI: u32 = 1;
|
|
||||||
pub const __USE_XOPEN2KXSI: u32 = 1;
|
|
||||||
pub const __USE_LARGEFILE: u32 = 1;
|
|
||||||
pub const __USE_LARGEFILE64: u32 = 1;
|
|
||||||
pub const __WORDSIZE: u32 = 64;
|
|
||||||
pub const __WORDSIZE_TIME64_COMPAT32: u32 = 1;
|
|
||||||
pub const __SYSCALL_WORDSIZE: u32 = 64;
|
|
||||||
pub const __TIMESIZE: u32 = 64;
|
|
||||||
pub const __USE_MISC: u32 = 1;
|
|
||||||
pub const __USE_ATFILE: u32 = 1;
|
|
||||||
pub const __USE_DYNAMIC_STACK_SIZE: u32 = 1;
|
|
||||||
pub const __USE_GNU: u32 = 1;
|
|
||||||
pub const __USE_FORTIFY_LEVEL: u32 = 0;
|
|
||||||
pub const __GLIBC_USE_DEPRECATED_GETS: u32 = 0;
|
|
||||||
pub const __GLIBC_USE_DEPRECATED_SCANF: u32 = 0;
|
|
||||||
pub const __GLIBC_USE_C2X_STRTOL: u32 = 1;
|
|
||||||
pub const _STDC_PREDEF_H: u32 = 1;
|
|
||||||
pub const __STDC_IEC_559__: u32 = 1;
|
|
||||||
pub const __STDC_IEC_60559_BFP__: u32 = 201404;
|
|
||||||
pub const __STDC_IEC_559_COMPLEX__: u32 = 1;
|
|
||||||
pub const __STDC_IEC_60559_COMPLEX__: u32 = 201404;
|
|
||||||
pub const __STDC_ISO_10646__: u32 = 201706;
|
|
||||||
pub const __GNU_LIBRARY__: u32 = 6;
|
|
||||||
pub const __GLIBC__: u32 = 2;
|
|
||||||
pub const __GLIBC_MINOR__: u32 = 39;
|
|
||||||
pub const _SYS_CDEFS_H: u32 = 1;
|
|
||||||
pub const __glibc_c99_flexarr_available: u32 = 1;
|
|
||||||
pub const __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI: u32 = 0;
|
|
||||||
pub const __HAVE_GENERIC_SELECTION: u32 = 0;
|
|
||||||
pub const __GLIBC_USE_LIB_EXT2: u32 = 1;
|
|
||||||
pub const __GLIBC_USE_IEC_60559_BFP_EXT: u32 = 1;
|
|
||||||
pub const __GLIBC_USE_IEC_60559_BFP_EXT_C2X: u32 = 1;
|
|
||||||
pub const __GLIBC_USE_IEC_60559_EXT: u32 = 1;
|
|
||||||
pub const __GLIBC_USE_IEC_60559_FUNCS_EXT: u32 = 1;
|
|
||||||
pub const __GLIBC_USE_IEC_60559_FUNCS_EXT_C2X: u32 = 1;
|
|
||||||
pub const __GLIBC_USE_IEC_60559_TYPES_EXT: u32 = 1;
|
|
||||||
pub const _BITS_TYPES_H: u32 = 1;
|
|
||||||
pub const _BITS_TYPESIZES_H: u32 = 1;
|
|
||||||
pub const __OFF_T_MATCHES_OFF64_T: u32 = 1;
|
|
||||||
pub const __INO_T_MATCHES_INO64_T: u32 = 1;
|
|
||||||
pub const __RLIM_T_MATCHES_RLIM64_T: u32 = 1;
|
|
||||||
pub const __STATFS_MATCHES_STATFS64: u32 = 1;
|
|
||||||
pub const __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64: u32 = 1;
|
|
||||||
pub const __FD_SETSIZE: u32 = 1024;
|
|
||||||
pub const _BITS_TIME64_H: u32 = 1;
|
|
||||||
pub const _BITS_WCHAR_H: u32 = 1;
|
|
||||||
pub const _BITS_STDINT_INTN_H: u32 = 1;
|
|
||||||
pub const _BITS_STDINT_UINTN_H: u32 = 1;
|
|
||||||
pub const _BITS_STDINT_LEAST_H: u32 = 1;
|
|
||||||
pub const INT8_MIN: i32 = -128;
|
|
||||||
pub const INT16_MIN: i32 = -32768;
|
|
||||||
pub const INT32_MIN: i32 = -2147483648;
|
|
||||||
pub const INT8_MAX: u32 = 127;
|
|
||||||
pub const INT16_MAX: u32 = 32767;
|
|
||||||
pub const INT32_MAX: u32 = 2147483647;
|
|
||||||
pub const UINT8_MAX: u32 = 255;
|
|
||||||
pub const UINT16_MAX: u32 = 65535;
|
|
||||||
pub const UINT32_MAX: u32 = 4294967295;
|
|
||||||
pub const INT_LEAST8_MIN: i32 = -128;
|
|
||||||
pub const INT_LEAST16_MIN: i32 = -32768;
|
|
||||||
pub const INT_LEAST32_MIN: i32 = -2147483648;
|
|
||||||
pub const INT_LEAST8_MAX: u32 = 127;
|
|
||||||
pub const INT_LEAST16_MAX: u32 = 32767;
|
|
||||||
pub const INT_LEAST32_MAX: u32 = 2147483647;
|
|
||||||
pub const UINT_LEAST8_MAX: u32 = 255;
|
|
||||||
pub const UINT_LEAST16_MAX: u32 = 65535;
|
|
||||||
pub const UINT_LEAST32_MAX: u32 = 4294967295;
|
|
||||||
pub const INT_FAST8_MIN: i32 = -128;
|
|
||||||
pub const INT_FAST16_MIN: i64 = -9223372036854775808;
|
|
||||||
pub const INT_FAST32_MIN: i64 = -9223372036854775808;
|
|
||||||
pub const INT_FAST8_MAX: u32 = 127;
|
|
||||||
pub const INT_FAST16_MAX: u64 = 9223372036854775807;
|
|
||||||
pub const INT_FAST32_MAX: u64 = 9223372036854775807;
|
|
||||||
pub const UINT_FAST8_MAX: u32 = 255;
|
|
||||||
pub const UINT_FAST16_MAX: i32 = -1;
|
|
||||||
pub const UINT_FAST32_MAX: i32 = -1;
|
|
||||||
pub const INTPTR_MIN: i64 = -9223372036854775808;
|
|
||||||
pub const INTPTR_MAX: u64 = 9223372036854775807;
|
|
||||||
pub const UINTPTR_MAX: i32 = -1;
|
|
||||||
pub const PTRDIFF_MIN: i64 = -9223372036854775808;
|
|
||||||
pub const PTRDIFF_MAX: u64 = 9223372036854775807;
|
|
||||||
pub const SIG_ATOMIC_MIN: i32 = -2147483648;
|
|
||||||
pub const SIG_ATOMIC_MAX: u32 = 2147483647;
|
|
||||||
pub const SIZE_MAX: i32 = -1;
|
|
||||||
pub const WINT_MIN: u32 = 0;
|
|
||||||
pub const WINT_MAX: u32 = 4294967295;
|
|
||||||
pub const INT8_WIDTH: u32 = 8;
|
|
||||||
pub const UINT8_WIDTH: u32 = 8;
|
|
||||||
pub const INT16_WIDTH: u32 = 16;
|
|
||||||
pub const UINT16_WIDTH: u32 = 16;
|
|
||||||
pub const INT32_WIDTH: u32 = 32;
|
|
||||||
pub const UINT32_WIDTH: u32 = 32;
|
|
||||||
pub const INT64_WIDTH: u32 = 64;
|
|
||||||
pub const UINT64_WIDTH: u32 = 64;
|
|
||||||
pub const INT_LEAST8_WIDTH: u32 = 8;
|
|
||||||
pub const UINT_LEAST8_WIDTH: u32 = 8;
|
|
||||||
pub const INT_LEAST16_WIDTH: u32 = 16;
|
|
||||||
pub const UINT_LEAST16_WIDTH: u32 = 16;
|
|
||||||
pub const INT_LEAST32_WIDTH: u32 = 32;
|
|
||||||
pub const UINT_LEAST32_WIDTH: u32 = 32;
|
|
||||||
pub const INT_LEAST64_WIDTH: u32 = 64;
|
|
||||||
pub const UINT_LEAST64_WIDTH: u32 = 64;
|
|
||||||
pub const INT_FAST8_WIDTH: u32 = 8;
|
|
||||||
pub const UINT_FAST8_WIDTH: u32 = 8;
|
|
||||||
pub const INT_FAST16_WIDTH: u32 = 64;
|
|
||||||
pub const UINT_FAST16_WIDTH: u32 = 64;
|
|
||||||
pub const INT_FAST32_WIDTH: u32 = 64;
|
|
||||||
pub const UINT_FAST32_WIDTH: u32 = 64;
|
|
||||||
pub const INT_FAST64_WIDTH: u32 = 64;
|
|
||||||
pub const UINT_FAST64_WIDTH: u32 = 64;
|
|
||||||
pub const INTPTR_WIDTH: u32 = 64;
|
|
||||||
pub const UINTPTR_WIDTH: u32 = 64;
|
|
||||||
pub const INTMAX_WIDTH: u32 = 64;
|
|
||||||
pub const UINTMAX_WIDTH: u32 = 64;
|
|
||||||
pub const PTRDIFF_WIDTH: u32 = 64;
|
|
||||||
pub const SIG_ATOMIC_WIDTH: u32 = 32;
|
|
||||||
pub const SIZE_WIDTH: u32 = 64;
|
|
||||||
pub const WCHAR_WIDTH: u32 = 32;
|
|
||||||
pub const WINT_WIDTH: u32 = 32;
|
|
||||||
pub type __u_char = ::core::ffi::c_uchar;
|
pub type __u_char = ::core::ffi::c_uchar;
|
||||||
pub type __u_short = ::core::ffi::c_ushort;
|
pub type __u_short = ::core::ffi::c_ushort;
|
||||||
pub type __u_int = ::core::ffi::c_uint;
|
pub type __u_int = ::core::ffi::c_uint;
|
||||||
|
@ -257,7 +109,6 @@ pub const kZionPortCreate: u64 = 80;
|
||||||
pub const kZionPortSend: u64 = 81;
|
pub const kZionPortSend: u64 = 81;
|
||||||
pub const kZionPortRecv: u64 = 82;
|
pub const kZionPortRecv: u64 = 82;
|
||||||
pub const kZionPortPoll: u64 = 83;
|
pub const kZionPortPoll: u64 = 83;
|
||||||
pub const kZionIrqRegister: u64 = 88;
|
|
||||||
pub const kZionMsiIrqRegister: u64 = 89;
|
pub const kZionMsiIrqRegister: u64 = 89;
|
||||||
pub const kZionEndpointCreate: u64 = 96;
|
pub const kZionEndpointCreate: u64 = 96;
|
||||||
pub const kZionEndpointSend: u64 = 97;
|
pub const kZionEndpointSend: u64 = 97;
|
||||||
|
@ -274,6 +125,10 @@ pub const kZionSemaphoreCreate: u64 = 131;
|
||||||
pub const kZionSemaphoreWait: u64 = 132;
|
pub const kZionSemaphoreWait: u64 = 132;
|
||||||
pub const kZionSemaphoreSignal: u64 = 133;
|
pub const kZionSemaphoreSignal: u64 = 133;
|
||||||
pub const kZionDebug: u64 = 65536;
|
pub const kZionDebug: u64 = 65536;
|
||||||
|
pub const kZionPciRead: u64 = 69632;
|
||||||
|
pub const kZionPciCreateBound: u64 = 69633;
|
||||||
|
pub const kZionPciReadBound: u64 = 69634;
|
||||||
|
pub const kZionPciWriteBound: u64 = 69635;
|
||||||
pub const kZIrqKbd: u64 = 34;
|
pub const kZIrqKbd: u64 = 34;
|
||||||
pub const kZIrqPci1: u64 = 48;
|
pub const kZIrqPci1: u64 = 48;
|
||||||
pub const kZIrqPci2: u64 = 49;
|
pub const kZIrqPci2: u64 = 49;
|
||||||
|
@ -351,10 +206,6 @@ pub struct ZThreadStartReq {
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct ZThreadExitReq {}
|
pub struct ZThreadExitReq {}
|
||||||
extern "C" {
|
|
||||||
#[link_name = "\u{1}_Z11ZThreadExitv"]
|
|
||||||
pub fn ZThreadExit() -> z_err_t;
|
|
||||||
}
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct ZThreadWaitReq {
|
pub struct ZThreadWaitReq {
|
||||||
|
@ -473,12 +324,6 @@ pub struct ZPortPollReq {
|
||||||
}
|
}
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct ZIrqRegisterReq {
|
|
||||||
pub irq_num: u64,
|
|
||||||
pub port_cap: *mut z_cap_t,
|
|
||||||
}
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub struct ZMsiIrqRegisterReq {
|
pub struct ZMsiIrqRegisterReq {
|
||||||
pub irq_num: *mut u64,
|
pub irq_num: *mut u64,
|
||||||
pub port_cap: *mut z_cap_t,
|
pub port_cap: *mut z_cap_t,
|
||||||
|
@ -574,3 +419,36 @@ pub struct ZDebugReq {
|
||||||
pub message: *const ::core::ffi::c_char,
|
pub message: *const ::core::ffi::c_char,
|
||||||
pub size: u64,
|
pub size: u64,
|
||||||
}
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub struct ZPciReadReq {
|
||||||
|
pub pci_cap: z_cap_t,
|
||||||
|
pub bus: u8,
|
||||||
|
pub slot: u8,
|
||||||
|
pub func: u8,
|
||||||
|
pub offset: u8,
|
||||||
|
pub output: *mut u32,
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub struct ZPciCreateBoundReq {
|
||||||
|
pub pci_cap: z_cap_t,
|
||||||
|
pub bus: u8,
|
||||||
|
pub slot: u8,
|
||||||
|
pub func: u8,
|
||||||
|
pub new_cap: *mut z_cap_t,
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub struct ZPciReadBoundReq {
|
||||||
|
pub pci_cap: z_cap_t,
|
||||||
|
pub offset: u8,
|
||||||
|
pub data: *mut u32,
|
||||||
|
}
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
pub struct ZPciWriteBoundReq {
|
||||||
|
pub pci_cap: z_cap_t,
|
||||||
|
pub offset: u8,
|
||||||
|
pub data: u32,
|
||||||
|
}
|
||||||
|
|
|
@ -472,3 +472,25 @@ pub fn semaphone_wait(sem_cap: &Capability) -> Result<(), ZError> {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn pci_read(
|
||||||
|
pci_cap: &Capability,
|
||||||
|
bus: u8,
|
||||||
|
slot: u8,
|
||||||
|
func: u8,
|
||||||
|
offset: u8,
|
||||||
|
) -> Result<u32, ZError> {
|
||||||
|
let mut data: u32 = 0;
|
||||||
|
syscall(
|
||||||
|
zion::kZionPciRead,
|
||||||
|
&zion::ZPciReadReq {
|
||||||
|
pci_cap: pci_cap.raw(),
|
||||||
|
bus,
|
||||||
|
slot,
|
||||||
|
func,
|
||||||
|
offset,
|
||||||
|
output: &mut data as *mut u32,
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
Ok(data)
|
||||||
|
}
|
||||||
|
|
|
@ -36,13 +36,14 @@ fn spawn_from_vmmo(vmmo_cap: z_cap_t, server_cap: Capability) -> Result<(), ZErr
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn main() -> z_err_t {
|
extern "C" fn main() -> z_err_t {
|
||||||
let pci_region = MemoryRegion::from_cap(Capability::take(unsafe { BOOT_PCI_VMMO }))
|
|
||||||
.expect("Failed to create PCI region");
|
|
||||||
let fb_region = MemoryRegion::from_cap(Capability::take(unsafe { BOOT_FRAMEBUFFER_INFO_VMMO }))
|
let fb_region = MemoryRegion::from_cap(Capability::take(unsafe { BOOT_FRAMEBUFFER_INFO_VMMO }))
|
||||||
.expect("Failed to create Framebuffer region");
|
.expect("Failed to create Framebuffer region");
|
||||||
let context = Arc::new(
|
let context = Arc::new(
|
||||||
server::YellowstoneServerContext::new(pci_region, fb_region)
|
server::YellowstoneServerContext::new(
|
||||||
.expect("Failed to create yellowstone context"),
|
Capability::take(unsafe { BOOT_PCI_VMMO }),
|
||||||
|
fb_region,
|
||||||
|
)
|
||||||
|
.expect("Failed to create yellowstone context"),
|
||||||
);
|
);
|
||||||
let handler = server::YellowstoneServerImpl::new(context.clone());
|
let handler = server::YellowstoneServerImpl::new(context.clone());
|
||||||
let server = YellowstoneServer::new(handler).expect("Couldn't create yellowstone server");
|
let server = YellowstoneServer::new(handler).expect("Couldn't create yellowstone server");
|
||||||
|
|
|
@ -1,14 +1,29 @@
|
||||||
use mammoth::{cap::Capability, mem::MemoryRegion, zion::ZError};
|
use mammoth::{
|
||||||
|
cap::Capability,
|
||||||
|
mem::MemoryRegion,
|
||||||
|
syscall,
|
||||||
|
zion::{kZionPerm_All, ZError},
|
||||||
|
};
|
||||||
|
|
||||||
|
enum PciType {
|
||||||
|
Port(Capability),
|
||||||
|
Memory(MemoryRegion),
|
||||||
|
}
|
||||||
|
|
||||||
pub struct PciReader {
|
pub struct PciReader {
|
||||||
memory_region: MemoryRegion,
|
internal_type: PciType,
|
||||||
}
|
}
|
||||||
|
|
||||||
type DevPredicate = fn(u8, u8, u8) -> bool;
|
type DevPredicate = fn(u8, u8, u8) -> bool;
|
||||||
|
|
||||||
impl PciReader {
|
impl PciReader {
|
||||||
pub fn new(memory_region: MemoryRegion) -> Self {
|
pub fn new(capability: Capability) -> Self {
|
||||||
Self { memory_region }
|
let internal_type =
|
||||||
|
match MemoryRegion::from_cap(capability.duplicate(kZionPerm_All).unwrap()) {
|
||||||
|
Ok(mem) => PciType::Memory(mem),
|
||||||
|
Err(_) => PciType::Port(capability),
|
||||||
|
};
|
||||||
|
Self { internal_type }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_ahci_region(&self) -> Result<Capability, ZError> {
|
pub fn get_ahci_region(&self) -> Result<Capability, ZError> {
|
||||||
|
@ -28,15 +43,13 @@ impl PciReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn probe_pci(&self, pred: DevPredicate) -> Option<Capability> {
|
fn probe_pci(&self, pred: DevPredicate) -> Option<Capability> {
|
||||||
let base_header = self.pci_header(0, 0, 0);
|
if (self.header_type(0, 0, 0) & 0x80) == 0 {
|
||||||
if (base_header.header_type & 0x80) == 0 {
|
|
||||||
if let Some(dev) = self.probe_bus(pred, 0) {
|
if let Some(dev) = self.probe_bus(pred, 0) {
|
||||||
return Some(dev);
|
return Some(dev);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for fun in 0..8 {
|
for fun in 0..8 {
|
||||||
let fun_hdr = self.pci_header(0, 0, fun);
|
if self.vendor_id(0, 0, fun) != 0xFFFF {
|
||||||
if fun_hdr.vendor_id != 0xFFFF {
|
|
||||||
if let Some(dev) = self.probe_bus(pred, fun) {
|
if let Some(dev) = self.probe_bus(pred, fun) {
|
||||||
return Some(dev);
|
return Some(dev);
|
||||||
}
|
}
|
||||||
|
@ -56,8 +69,7 @@ impl PciReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn probe_device(&self, pred: DevPredicate, bus: u8, dev: u8) -> Option<Capability> {
|
fn probe_device(&self, pred: DevPredicate, bus: u8, dev: u8) -> Option<Capability> {
|
||||||
let device_base_header = self.pci_header(bus, dev, 0);
|
if self.vendor_id(bus, dev, 0) == 0xFFFF {
|
||||||
if device_base_header.vendor_id == 0xFFFF {
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +77,7 @@ impl PciReader {
|
||||||
return Some(dev);
|
return Some(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device_base_header.header_type & 0x80) != 0 {
|
if (self.header_type(bus, dev, 0) & 0x80) != 0 {
|
||||||
for fun in 1..8 {
|
for fun in 1..8 {
|
||||||
if let Some(dev) = self.probe_function(pred, bus, dev, fun) {
|
if let Some(dev) = self.probe_function(pred, bus, dev, fun) {
|
||||||
return Some(dev);
|
return Some(dev);
|
||||||
|
@ -76,37 +88,66 @@ impl PciReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn probe_function(&self, pred: DevPredicate, bus: u8, dev: u8, fun: u8) -> Option<Capability> {
|
fn probe_function(&self, pred: DevPredicate, bus: u8, dev: u8, fun: u8) -> Option<Capability> {
|
||||||
let function_header = self.pci_header(bus, dev, fun);
|
let (class, subclass, prog_interface) = self.class_codes(bus, dev, fun);
|
||||||
|
|
||||||
mammoth::debug!(
|
mammoth::debug!(
|
||||||
"PCI Function: {:#x} {:#x} {:#x}",
|
"PCI Function: {:#x} {:#x} {:#x}",
|
||||||
function_header.class_code,
|
class,
|
||||||
function_header.subclass,
|
subclass,
|
||||||
function_header.prog_interface
|
prog_interface
|
||||||
);
|
);
|
||||||
|
|
||||||
if pred(
|
if pred(class, subclass, prog_interface) {
|
||||||
function_header.class_code,
|
|
||||||
function_header.subclass,
|
|
||||||
function_header.prog_interface,
|
|
||||||
) {
|
|
||||||
mammoth::debug!("Found!");
|
mammoth::debug!("Found!");
|
||||||
let offset = pci_header_offset(bus, dev, fun);
|
Some(self.create_cap(bus, dev, fun))
|
||||||
Some(
|
|
||||||
self.memory_region
|
|
||||||
.duplicate(offset as u64, 0x1000)
|
|
||||||
.expect("Failed to duplicate PCI cap"),
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pci_header(&self, bus: u8, dev: u8, fun: u8) -> &PciHeader {
|
fn header_type(&self, bus: u8, dev: u8, fun: u8) -> u8 {
|
||||||
let offset = pci_header_offset(bus, dev, fun);
|
let data = self.read_at(bus, dev, fun, 0xC);
|
||||||
let header_slice: &[u8] =
|
|
||||||
&self.memory_region.slice()[offset..offset + size_of::<PciHeader>()];
|
((data >> 16) & 0xFF) as u8
|
||||||
unsafe { header_slice.as_ptr().cast::<PciHeader>().as_ref().unwrap() }
|
}
|
||||||
|
|
||||||
|
fn vendor_id(&self, bus: u8, dev: u8, fun: u8) -> u16 {
|
||||||
|
let data = self.read_at(bus, dev, fun, 0);
|
||||||
|
|
||||||
|
(data & 0xFFFF) as u16
|
||||||
|
}
|
||||||
|
|
||||||
|
fn class_codes(&self, bus: u8, dev: u8, fun: u8) -> (u8, u8, u8) {
|
||||||
|
let data = self.read_at(bus, dev, fun, 0x8);
|
||||||
|
|
||||||
|
let class = (data >> 24) as u8;
|
||||||
|
let subclass = ((data >> 16) & 0xFF) as u8;
|
||||||
|
let prog_if = ((data >> 8) & 0xFF) as u8;
|
||||||
|
|
||||||
|
(class, subclass, prog_if)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_at(&self, bus: u8, dev: u8, fun: u8, off: u8) -> u32 {
|
||||||
|
match &self.internal_type {
|
||||||
|
PciType::Memory(region) => {
|
||||||
|
let offset = pci_header_offset(bus, dev, fun);
|
||||||
|
let header_slice: &[u32] = ®ion.slice()[offset..offset + size_of::<PciHeader>()];
|
||||||
|
header_slice[(off >> 2) as usize]
|
||||||
|
}
|
||||||
|
PciType::Port(pci_cap) => syscall::pci_read(pci_cap, bus, dev, fun, off).unwrap(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_cap(&self, bus: u8, dev: u8, fun: u8) -> Capability {
|
||||||
|
match &self.internal_type {
|
||||||
|
PciType::Memory(region) => {
|
||||||
|
let offset = pci_header_offset(bus, dev, fun);
|
||||||
|
region
|
||||||
|
.duplicate(offset as u64, 0x1000)
|
||||||
|
.expect("Failed to duplicate PCI cap")
|
||||||
|
}
|
||||||
|
PciType::Port(_pci_cap) => todo!(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,13 +43,11 @@ impl YellowstoneServerContext {
|
||||||
green_mask_shift: fb_info.green_mask_shift as u64,
|
green_mask_shift: fb_info.green_mask_shift as u64,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl YellowstoneServerContext {
|
pub fn new(pci_cap: Capability, fb_region: MemoryRegion) -> Result<Self, ZError> {
|
||||||
pub fn new(pci_region: MemoryRegion, fb_region: MemoryRegion) -> Result<Self, ZError> {
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
registration_semaphore: mammoth::sync::Semaphore::new()?,
|
registration_semaphore: mammoth::sync::Semaphore::new()?,
|
||||||
pci_reader: PciReader::new(pci_region),
|
pci_reader: PciReader::new(pci_cap),
|
||||||
framebuffer_info_region: fb_region,
|
framebuffer_info_region: fb_region,
|
||||||
service_map: Mutex::new(BTreeMap::new()),
|
service_map: Mutex::new(BTreeMap::new()),
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
BUILD_DIR="${DIR}/../builddbg"
|
||||||
|
|
||||||
|
bash ${DIR}/build.sh
|
||||||
|
sudo sh ${DIR}/build_image.sh ${BUILD_DIR}/disk.img
|
||||||
|
|
||||||
|
BOCHS_ARGS=
|
||||||
|
if [[ $1 == "debug" ]]; then
|
||||||
|
BOCHS_ARGS+="-dbg"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# TODO Make this portable, build bochs as a part of toolchain?
|
||||||
|
~/opt/bochs/bin/bochs $BOCHS_ARGS -q
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
#! /bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
echo $DIR
|
||||||
|
|
||||||
|
BUILD_DIR="${DIR}/../builddbg"
|
||||||
|
|
||||||
|
pushd $BUILD_DIR
|
||||||
|
ninja
|
||||||
|
ninja install
|
||||||
|
|
||||||
|
CARGO_USR_ROOT="${DIR}/../sysroot/usr/"
|
||||||
|
CARGO_SYS_ROOT="${DIR}/../sysroot/"
|
||||||
|
|
||||||
|
# Need to pushd so rustup gets the toolchain from rust/rust_toolchain.toml
|
||||||
|
pushd "${DIR}/../rust"
|
||||||
|
|
||||||
|
for BIN in ${DIR}/../rust/usr/*/; do
|
||||||
|
cargo install --force --path "${BIN}" --root $CARGO_USR_ROOT
|
||||||
|
done
|
||||||
|
|
||||||
|
for BIN in ${DIR}/../rust/sys/*/; do
|
||||||
|
cargo install --all-features --force --path "${BIN}" --root $CARGO_SYS_ROOT
|
||||||
|
done
|
||||||
|
popd
|
||||||
|
|
||||||
|
popd
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
#!/us
|
#! /bin/bash
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
REPO_ROOT="$SCRIPT_DIR/.."
|
||||||
|
BUILD_DIR="$REPO_ROOT/builddbg"
|
||||||
|
|
||||||
if [[ $# -ne 1 ]]; then
|
if [[ $# -ne 1 ]]; then
|
||||||
echo "Must specify disk image name."
|
echo "Must specify disk image name."
|
||||||
fi
|
fi
|
||||||
|
@ -15,11 +19,14 @@ if [ -z "$dev" ]; then
|
||||||
fi
|
fi
|
||||||
echo "Loopback device: ${dev}"
|
echo "Loopback device: ${dev}"
|
||||||
|
|
||||||
|
EFI_DIR="$BUILD_DIR/efi"
|
||||||
|
SYSROOT="$BUILD_DIR/sysroot"
|
||||||
|
|
||||||
cleanup() {
|
cleanup() {
|
||||||
umount efi
|
umount $EFI_DIR
|
||||||
rm -rf efi
|
rm -rf $EFI_DIR
|
||||||
umount sysroot
|
umount $SYSROOT
|
||||||
rm -rf sysroot
|
rm -rf $SYSROOT
|
||||||
losetup -d $dev
|
losetup -d $dev
|
||||||
}
|
}
|
||||||
trap cleanup EXIT
|
trap cleanup EXIT
|
||||||
|
@ -30,22 +37,23 @@ mke2fs "${dev}p2"
|
||||||
|
|
||||||
limine bios-install "${dev}"
|
limine bios-install "${dev}"
|
||||||
|
|
||||||
mkdir -p efi/
|
|
||||||
mount "${dev}p1" efi/
|
|
||||||
|
|
||||||
mkdir -p efi/EFI/BOOT
|
mkdir -p $EFI_DIR
|
||||||
cp /usr/share/limine/BOOTX64.EFI efi/EFI/BOOT
|
mount "${dev}p1" $EFI_DIR
|
||||||
cp /usr/share/limine/limine-bios.sys efi/
|
|
||||||
cp ../zion/boot/limine.conf efi/
|
|
||||||
cp zion/zion efi/
|
|
||||||
mkdir -p efi/sys
|
|
||||||
cp ../sysroot/bin/yellowstone efi/sys/yellowstone
|
|
||||||
cp ../sysroot/bin/denali efi/sys/denali
|
|
||||||
cp ../sysroot/bin/victoriafalls efi/sys/victoriafalls
|
|
||||||
|
|
||||||
mkdir -p sysroot
|
mkdir -p $EFI_DIR/EFI/BOOT
|
||||||
mount "${dev}p2" sysroot/
|
cp /usr/share/limine/BOOTX64.EFI $EFI_DIR/EFI/BOOT
|
||||||
rsync -a ../sysroot .
|
cp /usr/share/limine/limine-bios.sys $EFI_DIR
|
||||||
ls sysroot/
|
cp $REPO_ROOT/zion/boot/limine.conf $EFI_DIR/
|
||||||
|
cp $BUILD_DIR/zion/zion $EFI_DIR/
|
||||||
|
mkdir -p $EFI_DIR/sys
|
||||||
|
cp $REPO_ROOT/sysroot/bin/yellowstone $EFI_DIR/sys/yellowstone
|
||||||
|
cp $REPO_ROOT/sysroot/bin/denali $EFI_DIR/sys/denali
|
||||||
|
cp $REPO_ROOT/sysroot/bin/victoriafalls $EFI_DIR/sys/victoriafalls
|
||||||
|
|
||||||
|
mkdir -p $SYSROOT
|
||||||
|
mount "${dev}p2" $SYSROOT
|
||||||
|
rsync -a "$REPO_ROOT/sysroot" $BUILD_DIR
|
||||||
|
ls $SYSROOT
|
||||||
|
|
||||||
chown drew:drew $1
|
chown drew:drew $1
|
||||||
|
|
|
@ -8,26 +8,9 @@ echo $DIR
|
||||||
|
|
||||||
BUILD_DIR="${DIR}/../builddbg"
|
BUILD_DIR="${DIR}/../builddbg"
|
||||||
|
|
||||||
pushd $BUILD_DIR
|
|
||||||
ninja
|
|
||||||
ninja install
|
|
||||||
|
|
||||||
CARGO_USR_ROOT="${DIR}/../sysroot/usr/"
|
bash ${DIR}/build.sh
|
||||||
CARGO_SYS_ROOT="${DIR}/../sysroot/"
|
sudo sh ${DIR}/build_image.sh ${BUILD_DIR}/disk.img
|
||||||
|
|
||||||
# Need to pushd so rustup gets the toolchain from rust/rust_toolchain.toml
|
|
||||||
pushd "${DIR}/../rust"
|
|
||||||
|
|
||||||
for BIN in ${DIR}/../rust/usr/*/; do
|
|
||||||
cargo install --force --path "${BIN}" --root $CARGO_USR_ROOT
|
|
||||||
done
|
|
||||||
|
|
||||||
for BIN in ${DIR}/../rust/sys/*/; do
|
|
||||||
cargo install --all-features --force --path "${BIN}" --root $CARGO_SYS_ROOT
|
|
||||||
done
|
|
||||||
popd
|
|
||||||
|
|
||||||
sudo sh ${DIR}/build_image.sh disk.img
|
|
||||||
|
|
||||||
QEMU_ARGS=
|
QEMU_ARGS=
|
||||||
if [[ $1 == "debug" ]]; then
|
if [[ $1 == "debug" ]]; then
|
||||||
|
@ -35,7 +18,7 @@ if [[ $1 == "debug" ]]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Use machine q35 to access PCI devices.
|
# Use machine q35 to access PCI devices.
|
||||||
qemu-system-x86_64 -machine q35 -d guest_errors -m 1G -serial stdio -hda disk.img ${QEMU_ARGS} -device nec-usb-xhci,id=xhci -device usb-kbd,bus=xhci.0
|
qemu-system-x86_64 -machine q35 -d guest_errors -m 1G -serial stdio -hda ${BUILD_DIR}/disk.img ${QEMU_ARGS} -device nec-usb-xhci,id=xhci -device usb-kbd,bus=xhci.0
|
||||||
popd
|
popd
|
||||||
|
|
||||||
# Extra options to add to this script in the future.
|
# Extra options to add to this script in the future.
|
||||||
|
|
|
@ -30,6 +30,7 @@ add_executable(zion
|
||||||
object/ipc_object.cpp
|
object/ipc_object.cpp
|
||||||
object/memory_object.cpp
|
object/memory_object.cpp
|
||||||
object/mutex.cpp
|
object/mutex.cpp
|
||||||
|
object/pci_port.cpp
|
||||||
object/port.cpp
|
object/port.cpp
|
||||||
object/process.cpp
|
object/process.cpp
|
||||||
object/reply_port.cpp
|
object/reply_port.cpp
|
||||||
|
@ -45,6 +46,7 @@ add_executable(zion
|
||||||
syscall/debug.cpp
|
syscall/debug.cpp
|
||||||
syscall/ipc.cpp
|
syscall/ipc.cpp
|
||||||
syscall/memory_object.cpp
|
syscall/memory_object.cpp
|
||||||
|
syscall/pci.cpp
|
||||||
syscall/process.cpp
|
syscall/process.cpp
|
||||||
syscall/synchronization.cpp
|
syscall/synchronization.cpp
|
||||||
syscall/syscall.cpp
|
syscall/syscall.cpp
|
||||||
|
|
|
@ -11,3 +11,13 @@ static inline uint8_t inb(uint16_t port) {
|
||||||
static inline void outb(uint16_t port, uint8_t value) {
|
static inline void outb(uint16_t port, uint8_t value) {
|
||||||
asm volatile("outb %0, %1" ::"a"(value), "Nd"(port));
|
asm volatile("outb %0, %1" ::"a"(value), "Nd"(port));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint32_t inl(uint16_t port) {
|
||||||
|
uint32_t result;
|
||||||
|
asm volatile("inl %1, %0" : "=a"(result) : "Nd"(port));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void outl(uint16_t port, uint32_t value) {
|
||||||
|
asm volatile("outl %0, %1" ::"a"(value), "Nd"(port));
|
||||||
|
}
|
||||||
|
|
|
@ -5,14 +5,18 @@
|
||||||
|
|
||||||
#define COM1 0x3f8
|
#define COM1 0x3f8
|
||||||
|
|
||||||
|
#define BOCHS_DBG 1
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
bool is_transmit_empty() { return (inb(COM1 + 5) & 0x20) != 0; }
|
bool is_transmit_empty() { return (inb(COM1 + 5) & 0x20) != 0; }
|
||||||
|
|
||||||
void dbgputchar(char c) {
|
void dbgputchar(char c) {
|
||||||
while (!is_transmit_empty())
|
while (!is_transmit_empty());
|
||||||
;
|
|
||||||
|
|
||||||
outb(COM1, c);
|
outb(COM1, c);
|
||||||
|
#if BOCHS_DBG
|
||||||
|
outb(0xe9, c);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void dbg(const glcr::StringView& str) {
|
void dbg(const glcr::StringView& str) {
|
||||||
|
@ -39,3 +43,52 @@ void dbgln(const glcr::StringView& str) {
|
||||||
dbg(str);
|
dbg(str);
|
||||||
dbg("\n");
|
dbg("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// Helper function to write a byte to a specified COM1 register offset
|
||||||
|
void write_serial_port(uint16_t offset, uint8_t value) {
|
||||||
|
outb(COM1 + offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to read a byte from a specified COM1 register offset
|
||||||
|
uint8_t read_serial_port(uint16_t offset) { return inb(COM1 + offset); }
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace serial {
|
||||||
|
|
||||||
|
// Function to initialize the serial port with a given baud rate
|
||||||
|
void initialize(uint32_t baud_rate) {
|
||||||
|
// Disable interrupts
|
||||||
|
write_serial_port(1, 0x00);
|
||||||
|
|
||||||
|
// Enable DLAB (Divisor Latch Access Bit) in Line Control Register (LCR)
|
||||||
|
write_serial_port(3, read_serial_port(3) | 0x80);
|
||||||
|
|
||||||
|
// Calculate the divisor
|
||||||
|
// Baud rate = 115200 / divisor (approximately)
|
||||||
|
uint16_t divisor = 115200 / baud_rate;
|
||||||
|
|
||||||
|
// Set the low byte of the divisor
|
||||||
|
write_serial_port(0, divisor & 0xFF);
|
||||||
|
|
||||||
|
// Set the high byte of the divisor
|
||||||
|
write_serial_port(1, (divisor >> 8) & 0xFF);
|
||||||
|
|
||||||
|
// Clear DLAB and set data bits, stop bits, and parity
|
||||||
|
// 8 data bits, 1 stop bit, no parity
|
||||||
|
write_serial_port(3, 0x03); // 00000011b
|
||||||
|
|
||||||
|
// Enable FIFO, clear buffers, set trigger level (e.g., 1 byte)
|
||||||
|
write_serial_port(2, 0xC7); // 11000111b
|
||||||
|
|
||||||
|
// Enable IRQs (optional, for interrupt-driven communication)
|
||||||
|
// write_serial_port(1, 0x01);
|
||||||
|
|
||||||
|
// Set Modem Control Register (MCR)
|
||||||
|
// Enable RTS, DTR, OUT1, OUT2, loopback off, IRQs enabled
|
||||||
|
write_serial_port(4, 0x0B); // 00001011b
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace serial
|
||||||
|
|
|
@ -37,3 +37,9 @@ void panic(const char* str, Args&&... args) {
|
||||||
#define UNREACHABLE \
|
#define UNREACHABLE \
|
||||||
panic("Unreachable {}, {}", glcr::StringView(__FILE__), __LINE__); \
|
panic("Unreachable {}, {}", glcr::StringView(__FILE__), __LINE__); \
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
|
|
||||||
|
namespace serial {
|
||||||
|
|
||||||
|
void initialize(uint32_t baud_rate);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -71,3 +71,14 @@ SYS1(SemaphoreWait, z_cap_t, semaphore_cap);
|
||||||
SYS1(SemaphoreSignal, z_cap_t, semaphore_cap);
|
SYS1(SemaphoreSignal, z_cap_t, semaphore_cap);
|
||||||
|
|
||||||
SYS2(Debug, const char*, message, uint64_t, size);
|
SYS2(Debug, const char*, message, uint64_t, size);
|
||||||
|
|
||||||
|
// TODO: These should be handled with a more generic user-space interface.
|
||||||
|
// To be honest we could just have an inl and outl interface that is provided to
|
||||||
|
// yellowstone and the extra ipc load would be a good stress test of our
|
||||||
|
// performance
|
||||||
|
SYS6(PciRead, z_cap_t, pci_cap, uint8_t, bus, uint8_t, slot, uint8_t, func,
|
||||||
|
uint8_t, offset, uint32_t*, output);
|
||||||
|
SYS5(PciCreateBound, z_cap_t, pci_cap, uint8_t, bus, uint8_t, slot, uint8_t,
|
||||||
|
func, z_cap_t*, new_cap);
|
||||||
|
SYS3(PciReadBound, z_cap_t, pci_cap, uint8_t, offset, uint32_t*, data);
|
||||||
|
SYS3(PciWriteBound, z_cap_t, pci_cap, uint8_t, offset, uint32_t, data);
|
||||||
|
|
|
@ -67,6 +67,11 @@ const uint64_t kZionSemaphoreSignal = 0x85;
|
||||||
// Debugging Calls.
|
// Debugging Calls.
|
||||||
const uint64_t kZionDebug = 0x1'0000;
|
const uint64_t kZionDebug = 0x1'0000;
|
||||||
|
|
||||||
|
const uint64_t kZionPciRead = 0x1'1000;
|
||||||
|
const uint64_t kZionPciCreateBound = 0x1'1001;
|
||||||
|
const uint64_t kZionPciReadBound = 0x1'1002;
|
||||||
|
const uint64_t kZionPciWriteBound = 0x1'1003;
|
||||||
|
|
||||||
// Irq Types
|
// Irq Types
|
||||||
const uint64_t kZIrqKbd = 0x22;
|
const uint64_t kZIrqKbd = 0x22;
|
||||||
const uint64_t kZIrqPci1 = 0x30;
|
const uint64_t kZIrqPci1 = 0x30;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "debug/debug.h"
|
#include "debug/debug.h"
|
||||||
#include "include/zcall.h"
|
#include "include/zcall.h"
|
||||||
#include "memory/paging_util.h"
|
#include "memory/paging_util.h"
|
||||||
|
#include "object/pci_port.h"
|
||||||
#include "object/process.h"
|
#include "object/process.h"
|
||||||
#include "object/thread.h"
|
#include "object/thread.h"
|
||||||
#include "scheduler/process_manager.h"
|
#include "scheduler/process_manager.h"
|
||||||
|
@ -187,7 +188,9 @@ void LoadInitProgram() {
|
||||||
WriteFramebufferVmmo(port);
|
WriteFramebufferVmmo(port);
|
||||||
|
|
||||||
if (WritePciVmmo(port, Z_BOOT_PCI_VMMO) != glcr::OK) {
|
if (WritePciVmmo(port, Z_BOOT_PCI_VMMO) != glcr::OK) {
|
||||||
panic("Failed to provide PCI info to init.");
|
dbgln("Failed to find PCIe space, creating PCI IO Port Cap");
|
||||||
|
auto pci_port = PciPort::Create();
|
||||||
|
port->WriteKernel(Z_BOOT_PCI_VMMO, MakeRefCounted<Capability>(pci_port));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start process.
|
// Start process.
|
||||||
|
|
|
@ -16,6 +16,10 @@ class KernelObject : public glcr::RefCounted<KernelObject> {
|
||||||
REPLY_PORT = 0x8,
|
REPLY_PORT = 0x8,
|
||||||
MUTEX = 0x9,
|
MUTEX = 0x9,
|
||||||
SEMAPHORE = 0x10,
|
SEMAPHORE = 0x10,
|
||||||
|
|
||||||
|
// Temporary.
|
||||||
|
PCI_CAP = 0x100,
|
||||||
|
PCI_BOUND_CAP = 0x101,
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual uint64_t TypeTag() = 0;
|
virtual uint64_t TypeTag() = 0;
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
#include "object/pci_port.h"
|
||||||
|
|
||||||
|
#include "common/port.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const uint16_t PCI_ADDR_PORT = 0xCF8;
|
||||||
|
const uint16_t PCI_DATA_PORT = 0xCFC;
|
||||||
|
|
||||||
|
uint32_t AddressOf(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset) {
|
||||||
|
uint32_t lbus = (uint32_t)bus;
|
||||||
|
uint32_t lslot = (uint32_t)slot;
|
||||||
|
uint32_t lfunc = (uint32_t)func;
|
||||||
|
|
||||||
|
return (uint32_t)((lbus << 16) | (lslot << 11) | (lfunc << 8) |
|
||||||
|
(offset & 0xFC) | ((uint32_t)0x80000000));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t PciReadAtOffset(uint8_t bus, uint8_t slot, uint8_t func,
|
||||||
|
uint8_t offset) {
|
||||||
|
uint32_t address = AddressOf(bus, slot, func, offset);
|
||||||
|
outl(PCI_ADDR_PORT, address);
|
||||||
|
return inl(PCI_DATA_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PciWriteAtOffset(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset,
|
||||||
|
uint32_t word) {
|
||||||
|
uint32_t address = AddressOf(bus, slot, func, offset);
|
||||||
|
outl(PCI_ADDR_PORT, address);
|
||||||
|
outl(PCI_DATA_PORT, word);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
uint32_t PciPort::ReadAtOffset(uint8_t bus, uint8_t slot, uint8_t func,
|
||||||
|
uint8_t offset) {
|
||||||
|
return PciReadAtOffset(bus, slot, func, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t PciPortBound::Read(uint8_t offset) {
|
||||||
|
return PciReadAtOffset(bus_, slot_, func_, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PciPortBound::Write(uint8_t offset, uint32_t data) {
|
||||||
|
PciWriteAtOffset(bus_, slot_, func_, offset, data);
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
#include <glacier/memory/ref_ptr.h>
|
||||||
|
|
||||||
|
#include "include/ztypes.h"
|
||||||
|
#include "object/kernel_object.h"
|
||||||
|
|
||||||
|
class PciPort;
|
||||||
|
class PciPortBound;
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct KernelObjectTag<PciPort> {
|
||||||
|
static const uint64_t type = KernelObject::PCI_CAP;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PciPort : public KernelObject {
|
||||||
|
public:
|
||||||
|
static uint64_t DefaultPermissions() {
|
||||||
|
return kZionPerm_Write | kZionPerm_Read | kZionPerm_Duplicate |
|
||||||
|
kZionPerm_Transmit;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t TypeTag() override { return KernelObject::PCI_CAP; }
|
||||||
|
|
||||||
|
static glcr::RefPtr<PciPort> Create() { return glcr::AdoptPtr(new PciPort); }
|
||||||
|
|
||||||
|
uint32_t ReadAtOffset(uint8_t bus, uint8_t slot, uint8_t func,
|
||||||
|
uint8_t offset);
|
||||||
|
|
||||||
|
private:
|
||||||
|
PciPort() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct KernelObjectTag<PciPortBound> {
|
||||||
|
static const uint64_t type = KernelObject::PCI_BOUND_CAP;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PciPortBound : public KernelObject {
|
||||||
|
public:
|
||||||
|
static uint64_t DefaultPermissions() {
|
||||||
|
return kZionPerm_Write | kZionPerm_Read | kZionPerm_Duplicate;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t TypeTag() override { return KernelObject::PCI_BOUND_CAP; }
|
||||||
|
|
||||||
|
static glcr::RefPtr<PciPortBound> Create(uint8_t bus, uint8_t slot,
|
||||||
|
uint8_t func) {
|
||||||
|
return glcr::AdoptPtr(new PciPortBound(bus, slot, func));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Read(uint8_t offset);
|
||||||
|
void Write(uint8_t offset, uint32_t data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
PciPortBound(uint8_t bus, uint8_t slot, uint8_t func)
|
||||||
|
: bus_(bus), slot_(slot), func_(func) {}
|
||||||
|
|
||||||
|
uint8_t bus_;
|
||||||
|
uint8_t slot_;
|
||||||
|
uint8_t func_;
|
||||||
|
};
|
|
@ -51,6 +51,9 @@ Thread::Thread(Process& proc, uint64_t tid)
|
||||||
if (reinterpret_cast<uint64_t>(fx_data_) & 0x8) {
|
if (reinterpret_cast<uint64_t>(fx_data_) & 0x8) {
|
||||||
fx_data_ += 8;
|
fx_data_ += 8;
|
||||||
}
|
}
|
||||||
|
for (uint16_t i = 0; i < 512; i++) {
|
||||||
|
fx_data_[i] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t Thread::pid() const { return process_.id(); }
|
uint64_t Thread::pid() const { return process_.id(); }
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
#include "syscall/pci.h"
|
||||||
|
|
||||||
|
#include "object/pci_port.h"
|
||||||
|
#include "scheduler/scheduler.h"
|
||||||
|
|
||||||
|
z_err_t PciRead(ZPciReadReq* req) {
|
||||||
|
auto& curr_proc = gScheduler->CurrentProcess();
|
||||||
|
auto pci_cap = curr_proc.GetCapability(req->pci_cap);
|
||||||
|
RET_ERR(ValidateCapability<PciPort>(pci_cap, kZionPerm_Read));
|
||||||
|
|
||||||
|
*req->output = pci_cap->obj<PciPort>()->ReadAtOffset(req->bus, req->slot,
|
||||||
|
req->func, req->offset);
|
||||||
|
|
||||||
|
return glcr::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
z_err_t PciCreateBound(ZPciCreateBoundReq* req) {
|
||||||
|
auto& curr_proc = gScheduler->CurrentProcess();
|
||||||
|
auto pci_cap = curr_proc.GetCapability(req->pci_cap);
|
||||||
|
RET_ERR(ValidateCapability<PciPort>(pci_cap, kZionPerm_Duplicate));
|
||||||
|
|
||||||
|
*req->new_cap = curr_proc.AddNewCapability(
|
||||||
|
PciPortBound::Create(req->bus, req->slot, req->func));
|
||||||
|
return glcr::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
z_err_t PciReadBound(ZPciReadBoundReq* req) {
|
||||||
|
auto& curr_proc = gScheduler->CurrentProcess();
|
||||||
|
auto pci_cap = curr_proc.GetCapability(req->pci_cap);
|
||||||
|
RET_ERR(ValidateCapability<PciPortBound>(pci_cap, kZionPerm_Read));
|
||||||
|
|
||||||
|
*req->data = pci_cap->obj<PciPortBound>()->Read(req->offset);
|
||||||
|
|
||||||
|
return glcr::OK;
|
||||||
|
}
|
||||||
|
z_err_t PciWriteBound(ZPciWriteBoundReq* req) {
|
||||||
|
auto& curr_proc = gScheduler->CurrentProcess();
|
||||||
|
auto pci_cap = curr_proc.GetCapability(req->pci_cap);
|
||||||
|
RET_ERR(ValidateCapability<PciPortBound>(pci_cap, kZionPerm_Write));
|
||||||
|
|
||||||
|
pci_cap->obj<PciPortBound>()->Write(req->offset, req->data);
|
||||||
|
|
||||||
|
return glcr::OK;
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
#include "include/zcall.h"
|
||||||
|
|
||||||
|
z_err_t PciRead(ZPciReadReq* req);
|
||||||
|
z_err_t PciCreateBound(ZPciCreateBoundReq* req);
|
||||||
|
z_err_t PciReadBound(ZPciReadBoundReq* req);
|
||||||
|
z_err_t PciWriteBound(ZPciWriteBoundReq* req);
|
|
@ -20,6 +20,7 @@
|
||||||
#include "syscall/syscall.h"
|
#include "syscall/syscall.h"
|
||||||
|
|
||||||
extern "C" void zion() {
|
extern "C" void zion() {
|
||||||
|
serial::initialize(9600);
|
||||||
dbgln("[boot] Init GDT & IDT.");
|
dbgln("[boot] Init GDT & IDT.");
|
||||||
InitGdt();
|
InitGdt();
|
||||||
InitIdt();
|
InitIdt();
|
||||||
|
|
Loading…
Reference in New Issue