Compare commits

...

4 Commits

3 changed files with 56 additions and 26 deletions

View File

@ -35,19 +35,30 @@ struct A1
ulong address = Hurl.A1_BASE + allocated; ulong address = Hurl.A1_BASE + allocated;
ulong mapped_limit = round_up_power_2(address, PAGE_SIZE); ulong current_limit = round_up_power_2(address, PAGE_SIZE);
allocated += size; allocated += size;
ulong desired_limit = round_up_power_2(Hurl.A1_BASE + allocated, PAGE_SIZE); ulong desired_limit = round_up_power_2(Hurl.A1_BASE + allocated, PAGE_SIZE);
while (desired_limit > mapped_limit) while (desired_limit > current_limit)
{ {
void * page = Hippo.allocate_page(); void * page = Hippo.allocate_page();
Hurl.map(Hurl.A1_BASE + mapped_limit, page, PT_WRITABLE); Hurl.map(current_limit, page, PT_WRITABLE);
mapped_limit += PAGE_SIZE; current_limit += PAGE_SIZE;
} }
return cast(void *)address; return cast(void *)address;
} }
/**
* Allocate memory to store an instance of a given type.
*
* @return Address of allocated memory. This address will always be aligned
* to a multiple of 16 bytes.
*/
public static T * allocate(T)()
{
return cast(T *)allocate(T.sizeof);
}
} }

View File

@ -2,6 +2,7 @@ module hulk.pci;
import hulk.cpu; import hulk.cpu;
import hulk.klog; import hulk.klog;
import hulk.hurl.a1;
struct Pci struct Pci
{ {
@ -23,6 +24,43 @@ struct Pci
ubyte function_nr; ubyte function_nr;
} }
struct Device
{
Address address;
ushort vendor_id;
ushort device_id;
ubyte class_id;
ubyte subclass_id;
ubyte if_id;
void initialize(Address address, ushort vendor_id, ushort device_id)
{
this.vendor_id = vendor_id;
this.device_id = device_id;
uint reg2 = read_config_register(address, 2u);
class_id = (reg2 >> 24u) & 0xFFu;
subclass_id = (reg2 >> 16u) & 0xFFu;
if_id = (reg2 >> 8u) & 0xFFu;
Klog.writefln("Found PCI device %04x:%04x (%02x:%02x:%02x) at %02u:%02u.%u",
vendor_id, device_id,
class_id, subclass_id, if_id,
address.bus_nr, address.device_nr, address.function_nr);
init_device(class_id, subclass_id, if_id);
if (address.function_nr == 0u)
{
uint reg3 = read_config_register(address, 3u);
if ((reg3 & (1u << 23u)) != 0u)
{
/* Multi-function device found. */
for (address.function_nr = 1u; address.function_nr < 8u; address.function_nr++)
{
scan(address);
}
}
}
}
}
struct SerialBusController struct SerialBusController
{ {
enum ID = 0x0Cu; enum ID = 0x0Cu;
@ -91,29 +129,10 @@ struct Pci
ulong reg0 = read_config_register(address, 0u); ulong reg0 = read_config_register(address, 0u);
if (reg0 != 0xFFFFFFFFu) if (reg0 != 0xFFFFFFFFu)
{ {
uint reg2 = read_config_register(address, 2u);
ushort vendor_id = reg0 & 0xFFFFu; ushort vendor_id = reg0 & 0xFFFFu;
ushort device_id = (reg0 >> 16u) & 0xFFFFu; ushort device_id = (reg0 >> 16u) & 0xFFFFu;
ubyte class_id = (reg2 >> 24u) & 0xFFu; Device * device = A1.allocate!Device();
ubyte subclass_id = (reg2 >> 16u) & 0xFFu; device.initialize(address, vendor_id, device_id);
ubyte if_id = (reg2 >> 8u) & 0xFFu;
Klog.writefln("Found PCI device %04x:%04x (%02x:%02x:%02x) at %02u:%02u.%u",
vendor_id, device_id,
class_id, subclass_id, if_id,
address.bus_nr, address.device_nr, address.function_nr);
init_device(class_id, subclass_id, if_id);
if (address.function_nr == 0u)
{
uint reg3 = read_config_register(address, 3u);
if ((reg3 & (1u << 23u)) != 0u)
{
/* Multi-function device found. */
for (address.function_nr = 1u; address.function_nr < 8u; address.function_nr++)
{
scan(address);
}
}
}
} }
} }

View File

@ -11,7 +11,7 @@ module hulk.util;
* *
* @return Rounded up value. * @return Rounded up value.
*/ */
T round_up_power_2(T)(T v, T p) ulong round_up_power_2(ulong v, ulong p)
{ {
return (v + p - 1u) & ~(p - 1u); return (v + p - 1u) & ~(p - 1u);
} }