tawasuyu

tawasuyu/brahman

Rust 563TOML 212Markdown 66JSON 198014 Definitions

⎇ main renaser/kernel/src/drivers/pci.rs Rust · 76 lines · 3.4 KB History Who touched what raw

feat: integra renaser (kernel SASOS bare-metal) al monorepo e2272c0ed · sergio ·

1// =============================================================================
2//  renaser :: kernel/src/drivers/pci.rs — Fase 6.1 :: el acceso al bus PCI
3// -----------------------------------------------------------------------------
4//  El cargador `bootloader` entrega el mapa de memoria y el framebuffer, pero
5//  NO un censo de perifericos: descubrir el disco es tarea del kernel. Aqui
6//  renaser habla con el espacio de configuracion del bus PCI a traves del
7//  mecanismo #1 —los puertos 0xCF8 (direccion) y 0xCFC (datos)—.
8//
9//  Este modulo provee `CamPuertos`, una implementacion del rasgo
10//  `ConfigurationAccess` de `virtio-drivers`: la crate enumera el bus y mapea
11//  los BARs del dispositivo apoyandose en estas dos funciones de acceso.
12// =============================================================================
13
14use virtio_drivers::transport::pci::bus::{ConfigurationAccess, DeviceFunction};
15use x86_64::instructions::port::Port;
16
17/// Puerto de DIRECCION del mecanismo de configuracion PCI #1.
18const CONFIG_ADDRESS: u16 = 0xCF8;
19/// Puerto de DATOS del mecanismo de configuracion PCI #1.
20const CONFIG_DATA: u16 = 0xCFC;
21
22/// Compone la palabra de direccion del mecanismo #1: bit 31 de habilitacion,
23/// bus, dispositivo, funcion y offset de registro alineado a dword.
24fn direccion(device_function: DeviceFunction, offset: u8) -> u32 {
25    0x8000_0000
26        | ((device_function.bus as u32) << 16)
27        | ((device_function.device as u32) << 11)
28        | ((device_function.function as u32) << 8)
29        | ((offset as u32) & 0xFC)
30}
31
32/// Lee un registro de 32 bits del espacio de configuracion PCI.
33fn leer(device_function: DeviceFunction, offset: u8) -> u32 {
34    // SEGURIDAD: 0xCF8/0xCFC son los puertos del mecanismo de configuracion
35    // PCI #1, fijos en la arquitectura PC. La direccion lleva su bit de
36    // habilitacion y el offset alineado a dword, como exige el protocolo.
37    unsafe {
38        Port::<u32>::new(CONFIG_ADDRESS).write(direccion(device_function, offset));
39        Port::<u32>::new(CONFIG_DATA).read()
40    }
41}
42
43/// Escribe un registro de 32 bits en el espacio de configuracion PCI.
44fn escribir(device_function: DeviceFunction, offset: u8, dato: u32) {
45    // SEGURIDAD: vease `leer` — mismos puertos, mismo protocolo del 8259/PCI.
46    unsafe {
47        Port::<u32>::new(CONFIG_ADDRESS).write(direccion(device_function, offset));
48        Port::<u32>::new(CONFIG_DATA).write(dato);
49    }
50}
51
52/// Lee el registro «Interrupt Line» (byte bajo del offset 0x3C): la linea de
53/// IRQ del PIC que el firmware UEFI enruto y asigno a este dispositivo. Es el
54/// puente entre el descubrimiento PCI y el manejo de interrupciones (Fase 6.2).
55pub fn linea_irq(device_function: DeviceFunction) -> u8 {
56    (leer(device_function, 0x3C) & 0xFF) as u8
57}
58
59/// Acceso al espacio de configuracion PCI por puertos de E/S — el mecanismo #1.
60/// Es un tipo sin estado: toda la informacion viaja en cada llamada.
61pub struct CamPuertos;
62
63impl ConfigurationAccess for CamPuertos {
64    fn read_word(&self, device_function: DeviceFunction, register_offset: u8) -> u32 {
65        leer(device_function, register_offset)
66    }
67
68    fn write_word(&mut self, device_function: DeviceFunction, register_offset: u8, data: u32) {
69        escribir(device_function, register_offset, data);
70    }
71
72    unsafe fn unsafe_clone(&self) -> Self {
73        // `CamPuertos` no tiene estado: clonarlo es trivial y sin riesgo.
74        CamPuertos
75    }
76}