Пример #1
0
Файл: vm.c Проект: Kloniks/muk
static void test_vm_unmap(void)
{
  paddr_t paddr;
  vaddr_t vaddr;
  vm_as_t* as;

  as = vm_get_kernel_as();

  serial_printl("[?] test unmap\n");

  vaddr = (vaddr_t)0xb0000000;
  paddr = phys_alloc();
  vm_map(as, vaddr, paddr);

  /* no page fault
   */
  *(uint32_t*)vaddr = 0x2a;

  vm_unmap(as, vaddr);
  phys_free(paddr);

  /* page fault
   */
  *(uint32_t*)vaddr = 0x2a;
}
Пример #2
0
Файл: vm.c Проект: Kloniks/muk
static void test_vm_map(void)
{
  paddr_t paddr;
  vaddr_t vaddr;
  vm_as_t* as;

  as = vm_get_kernel_as();

  vaddr = (vaddr_t)0xb0000000;
  paddr = phys_alloc();

  vm_map(as, vaddr + PHYS_FRAME_SIZE * 0, paddr);
  *(volatile uint32_t*)(vaddr + PHYS_FRAME_SIZE * 0) = 0x2a;
  serial_printl("[?] --> %x\n",
		*(volatile uint32_t*)(vaddr + PHYS_FRAME_SIZE * 0));

  vm_map(as, vaddr + PHYS_FRAME_SIZE * 1, paddr);
  *(volatile uint32_t*)(vaddr + PHYS_FRAME_SIZE * 1) = 0x2a;
  serial_printl("[?] --> %x\n",
		*(volatile uint32_t*)(vaddr + PHYS_FRAME_SIZE * 1));

  vm_map(as, vaddr + PHYS_FRAME_SIZE * 2, paddr);
  *(volatile uint32_t*)(vaddr + PHYS_FRAME_SIZE * 2) = 0x2a;
  serial_printl("[?] --> %x\n",
		*(volatile uint32_t*)(vaddr + PHYS_FRAME_SIZE * 2));

  phys_free(paddr);
}
Пример #3
0
/* alloc a block */
void *
mm_alloc(size_t size)
{	
	unsigned bnum = (unsigned) ((size + 1) / (PHYS_PAGE_SIZE * 1024)) + 1; 
	// / PHYS_PAGE_SIZE + 1;
	return (void *)phys_alloc(bnum);
}
Пример #4
0
Файл: phys.c Проект: Kloniks/muk
void phys_test(void)
{
  paddr_t a;
  paddr_t b;
  paddr_t c;

  serial_printl("[?] test\n");

  phys_debug();

  a = phys_alloc();
  serial_printl("%x\n", (uint32_t)a);
  phys_free(a);

  a = phys_alloc();
  serial_printl("%x\n", (uint32_t)a);
  phys_free(a);

  phys_debug();
  a = phys_alloc();
  serial_printl("%x\n", (uint32_t)a);
  b = phys_alloc();
  serial_printl("%x\n", (uint32_t)b);
  c = phys_alloc();
  serial_printl("%x\n", (uint32_t)c);
  phys_debug();

  phys_free(a);
  phys_free(b);
  phys_free(c);

  phys_debug();
  b = phys_alloc_range(101);
  serial_printl("b == %x\n", (uint32_t)b);
  phys_free_range(b, 101);
  phys_debug();

  phys_debug();
}
Пример #5
0
Файл: vm.c Проект: Kloniks/muk
static void test_page_fault(void)
{
  volatile uint32_t* vaddr_0 = (uint32_t*)0xb0000000;
  volatile uint32_t* vaddr_1 = (uint32_t*)0xb0001000;
  volatile uint32_t* vaddr_2 = (uint32_t*)0xb0002000;
  paddr_t paddr = phys_alloc();
  vm_as_t* as;

  as = vm_get_kernel_as();

  vm_map(as, (vaddr_t)vaddr_0, paddr);
  vm_map(as, (vaddr_t)vaddr_1, paddr);
  vm_map(as, (vaddr_t)vaddr_2, paddr);

  *vaddr_0 = 0x2a;

  if ((*vaddr_0 != 0x2a) ||
      (*vaddr_0 != *vaddr_1) ||
      (*vaddr_0 != *vaddr_2))
    BUG();
}
Пример #6
0
/** Register a new PCI ATA channel.
 * @param pci_device	PCI device the channel is on.
 * @param idx		Channel index.
 * @param ctrl_base	Control registers base address.
 * @param cmd_base	Command registers base address.
 * @param bm_base	Bus master base address.
 * @param irq		IRQ number.
 * @return		Pointer to ATA channel structure if present. */
static ata_channel_t *pci_ata_channel_add(pci_device_t *pci_device, int idx, uint32_t ctrl_base,
                                          uint32_t cmd_base, uint32_t bm_base, uint32_t irq) {
	uint16_t pci_cmd_old, pci_cmd_new;
	pci_ata_channel_t *channel;
	bool dma = true;
	status_t ret;

	/* Configure the PCI device appropriately. */
	pci_cmd_old = pci_cmd_new = pci_config_read16(pci_device, PCI_CONFIG_COMMAND);
	pci_cmd_new &= ~PCI_COMMAND_INT_DISABLE;
	pci_cmd_new |= (PCI_COMMAND_IO | PCI_COMMAND_BUS_MASTER);
	if(pci_cmd_new != pci_cmd_old) {
		pci_config_write16(pci_device, PCI_CONFIG_COMMAND, pci_cmd_new);
		kprintf(LOG_DEBUG, "ata: reconfigured PCI device %d:%02x.%d (old: 0x%04x, new: 0x%04x)\n",
		        pci_device->bus, pci_device->device, pci_device->function,
		        pci_cmd_old, pci_cmd_new);
        }

	/* Check presence by writing a value to the low LBA port on the channel,
	 * then reading it back. If the value is the same, it is present. */
	out8(cmd_base + ATA_CMD_REG_LBA_LOW, 0xAB);
	if(in8(cmd_base + ATA_CMD_REG_LBA_LOW) != 0xAB) {
		if(pci_cmd_new != pci_cmd_old) {
			pci_config_write16(pci_device, PCI_CONFIG_COMMAND, pci_cmd_old);
		}
		return NULL;
	}

	/* Allocate our information structure. */
	channel = kmalloc(sizeof(*channel), MM_WAIT);
	channel->channel = NULL;
	channel->pci_device = pci_device;
	channel->ctrl_base = ctrl_base;
	channel->cmd_base = cmd_base;
	channel->bus_master_base = bm_base + (idx * 8);
	channel->irq = irq;
	channel->prdt = NULL;

	/* If the bus master is in simplex mode, disable DMA on the second
	 * channel. According to the Haiku code, Intel controllers use this for
	 * something other than simplex mode. */
	if(pci_device->vendor_id != 0x8086) {
		if(in8(bm_base + PCI_ATA_BM_REG_STATUS) & PCI_ATA_BM_STATUS_SIMPLEX && idx > 1) {
			dma = false;
		}
	}

	/* Allocate a PRDT if necessary. */
	if(dma) {
		phys_alloc(PRDT_SIZE, 0, 0, 0, (phys_ptr_t)0x100000000, MM_WAIT, &channel->prdt_phys);
		channel->prdt = phys_map(channel->prdt_phys, PRDT_SIZE, MM_WAIT);
	}

	/* Register the IRQ handler. */
	ret = irq_register(channel->irq, pci_ata_irq_handler, NULL, channel);
	if(ret != STATUS_SUCCESS) {
		kprintf(LOG_WARN, "ata: failed to register PCI ATA IRQ handler %u\n", channel->irq);
		if(dma) {
			phys_unmap(channel->prdt, PRDT_SIZE, true);
			phys_free(channel->prdt_phys, PRDT_SIZE);
		}
		kfree(channel);
		return NULL;
	}

	/* Try to register the ATA channel. */
	channel->channel = ata_sff_channel_add(pci_device->node, idx, &pci_ata_channel_ops, channel,
	                                       dma, PRDT_ENTRIES, (phys_ptr_t)0x100000000);
	if(!channel->channel) {
		irq_unregister(channel->irq, pci_ata_irq_handler, NULL, channel);
		if(dma) {
			phys_unmap(channel->prdt, PRDT_SIZE, true);
			phys_free(channel->prdt_phys, PRDT_SIZE);
		}
		kfree(channel);
		return NULL;
	}

	return channel->channel;
}