#include "block_device.h"
#include "block_device-priv.h"
#include "types.h"
#include "stdio.h"
#include "al/cpu.h" 

static volatile uint32_t *_ioc_block_device_addr;

inline void _ioc_block_device_init(uint32_t *addr)
{
  _ioc_block_device_addr = (volatile uint32_t*)addr;
}

inline int _ioc_read(size_t lba, void *buffer, size_t count)
{
  _ioc_block_device_addr[BLOCK_DEVICE_BUFFER] = (uint32_t)buffer;
  _ioc_block_device_addr[BLOCK_DEVICE_COUNT] = count;
  _ioc_block_device_addr[BLOCK_DEVICE_LBA] = lba;
  _ioc_block_device_addr[BLOCK_DEVICE_IRQ_ENABLE] = 0;
  _ioc_block_device_addr[BLOCK_DEVICE_OP] = BLOCK_DEVICE_READ;

  cpu_dcache_invalidate((const void *)buffer, _ioc_read_block_size()*count+1);
  
  while (_ioc_block_device_addr[BLOCK_DEVICE_STATUS] == BLOCK_DEVICE_BUSY)
  {
    if (_ioc_block_device_addr[BLOCK_DEVICE_STATUS] == BLOCK_DEVICE_READ_ERROR ||
        _ioc_block_device_addr[BLOCK_DEVICE_STATUS] == BLOCK_DEVICE_ERROR)
      return 1;
  }
    
  return 0;
}

inline uint32_t _ioc_read_block_size()
{
  return (uint32_t)_ioc_block_device_addr[BLOCK_DEVICE_BLOCK_SIZE];
}
